diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 1ee3e8c6b..ea9ed289a 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -7,6 +7,7 @@ MR-366 - Show PuTTY type and version on components check screen MR-938 - Adjust RDP Resolution list (ensure most common resolutions were available) MR-586 - Reduce HTTP/HTTPS document title length that is appended to the connection tab title + MR-975 - Replaced TreeView with TreeListView for displaying connection tree. This was a large change which separated the GUI from the domain model. Features/Enhancements: ---------------------- diff --git a/mRemoteNGTests/Config/Connections/SqlUpdateQueryBuilderTest.cs b/mRemoteNGTests/Config/Connections/SqlUpdateQueryBuilderTest.cs deleted file mode 100644 index 2fa590455..000000000 --- a/mRemoteNGTests/Config/Connections/SqlUpdateQueryBuilderTest.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using NUnit.Framework; -using mRemoteNG.Config.Connections; -using System.Data.SqlClient; - -namespace mRemoteNGTests.Config.Connections -{ - [TestFixture] - public class SqlUpdateQueryBuilderTest - { - private SqlUpdateQueryBuilder _sqlUpdateQueryBuilder; - - [SetUp] - public void Setup() - { - _sqlUpdateQueryBuilder = new SqlUpdateQueryBuilder(); - } - - [TearDown] - public void Teardown() - { - _sqlUpdateQueryBuilder = null; - } - - [Test] - public void SqlUpdateQueryBuilderReturnsSomeCommand() - { - SqlCommand command = _sqlUpdateQueryBuilder.BuildCommand(); - Assert.AreNotEqual(command.CommandText, ""); - } - } -} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Connections/SqlUpdateTimerTests.cs b/mRemoteNGTests/Config/Connections/SqlUpdateTimerTests.cs deleted file mode 100644 index ffc189489..000000000 --- a/mRemoteNGTests/Config/Connections/SqlUpdateTimerTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -using mRemoteNG.Config.Connections; -using NUnit.Framework; - -namespace mRemoteNGTests.Config.Connections -{ - [TestFixture] - public class SqlUpdateTimerTests - { - private SqlUpdateTimer sqlUpdateChecker; - - [SetUp] - public void SetupSqlUpdateChecker() - { - sqlUpdateChecker = new SqlUpdateTimer(); - } - - [TearDown] - public void TearDownSqlUpdateChecker() - { - sqlUpdateChecker.Dispose(); - sqlUpdateChecker = null; - } - - [Test] - public void EnableSQLUpdating() - { - sqlUpdateChecker.Enable(); - Assert.AreEqual(true, sqlUpdateChecker.IsUpdateCheckingEnabled()); - } - - [Test] - public void DisableSQLUpdating() - { - sqlUpdateChecker.Enable(); - Assert.AreEqual(true, sqlUpdateChecker.IsUpdateCheckingEnabled()); - sqlUpdateChecker.Disable(); - Assert.AreEqual(false, sqlUpdateChecker.IsUpdateCheckingEnabled()); - } - } -} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs b/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs new file mode 100644 index 000000000..6fff1b423 --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/DataTableSerializerTests.cs @@ -0,0 +1,128 @@ +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using NUnit.Framework; + +namespace mRemoteNGTests.Config.Serializers +{ + public class DataTableSerializerTests + { + private DataTableSerializer _dataTableSerializer; + private Save _saveFilter; + + [SetUp] + public void Setup() + { + _saveFilter = new Save(); + _dataTableSerializer = new DataTableSerializer(_saveFilter); + } + + [TearDown] + public void Teardown() + { + _saveFilter = null; + _dataTableSerializer = null; + } + + [Test] + public void AllItemsSerialized() + { + var model = CreateConnectionTreeModel(); + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows.Count, Is.EqualTo(3)); + } + + [Test] + public void UsernameSerializedWhenSaveSecurityAllowsIt() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Username = true; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["Username"], Is.Not.EqualTo("")); + } + + [Test] + public void DomainSerializedWhenSaveSecurityAllowsIt() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Domain = true; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["DomainName"], Is.Not.EqualTo("")); + } + + [Test] + public void PasswordSerializedWhenSaveSecurityAllowsIt() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Password = true; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["Password"], Is.Not.EqualTo("")); + } + + [Test] + public void InheritanceSerializedWhenSaveSecurityAllowsIt() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Inheritance = true; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["InheritUsername"], Is.Not.EqualTo("")); + } + + + + [Test] + public void UsernameNotSerializedWhenSaveSecurityDisabled() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Username = false; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["Username"], Is.EqualTo("")); + } + + [Test] + public void DomainNotSerializedWhenSaveSecurityDisabled() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Domain = false; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["DomainName"], Is.EqualTo("")); + } + + [Test] + public void PasswordNotSerializedWhenSaveSecurityDisabled() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Password = false; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["Password"], Is.EqualTo("")); + } + + [Test] + public void InheritanceNotSerializedWhenSaveSecurityDisabled() + { + var model = CreateConnectionTreeModel(); + _saveFilter.Inheritance = false; + var dataTable = _dataTableSerializer.Serialize(model); + Assert.That(dataTable.Rows[0]["InheritUsername"], Is.False); + } + + + private ConnectionTreeModel CreateConnectionTreeModel() + { + var model = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + var folder1 = new ContainerInfo {Name = "folder1", Username = "user1", Domain = "domain1", Password = "password1"}; + var con1 = new ConnectionInfo {Name = "Con1", Username = "user1", Domain = "domain1", Password = "password1" }; + var con2 = new ConnectionInfo {Name = "Con2", Username = "user2", Domain = "domain2", Password = "password2" }; + + root.AddChild(folder1); + root.AddChild(con2); + folder1.AddChild(con1); + model.AddRootNode(root); + return model; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/PortScanDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/PortScanDeserializerTests.cs new file mode 100644 index 000000000..e7025d653 --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/PortScanDeserializerTests.cs @@ -0,0 +1,61 @@ +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Tools; +using NUnit.Framework; + + +namespace mRemoteNGTests.Config.Serializers +{ + public class PortScanDeserializerTests + { + private PortScanDeserializer _deserializer; + private ConnectionInfo _importedConnectionInfo; + private const string ExpectedHostName = "server1.domain.com"; + private const string ExpectedDisplayName = "server1"; + private const ProtocolType ExpectedProtocolType = ProtocolType.SSH2; + + + + [OneTimeSetUp] + public void OnetimeSetup() + { + var host = new ScanHost("10.20.30.40") + { + HostName = "server1.domain.com", + SSH = true + }; + _deserializer = new PortScanDeserializer(new [] {host}, ProtocolType.SSH2); + _deserializer.Deserialize(); + var connectionTreeModel = _deserializer.Deserialize(); + var root = connectionTreeModel.RootNodes.First(); + _importedConnectionInfo = root.Children.First(); + } + + [OneTimeTearDown] + public void OnetimeTeardown() + { + _deserializer = null; + _importedConnectionInfo = null; + } + + [Test] + public void DisplayNameImported() + { + Assert.That(_importedConnectionInfo.Name, Is.EqualTo(ExpectedDisplayName)); + } + + [Test] + public void HostNameImported() + { + Assert.That(_importedConnectionInfo.Hostname, Is.EqualTo(ExpectedHostName)); + } + + [Test] + public void ProtocolImported() + { + Assert.That(_importedConnectionInfo.Protocol, Is.EqualTo(ExpectedProtocolType)); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/PuttyConnectionManagerDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/PuttyConnectionManagerDeserializerTests.cs new file mode 100644 index 000000000..f8d5fbe30 --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/PuttyConnectionManagerDeserializerTests.cs @@ -0,0 +1,112 @@ +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNGTests.Properties; +using NUnit.Framework; + + +namespace mRemoteNGTests.Config.Serializers +{ + public class PuttyConnectionManagerDeserializerTests + { + private PuttyConnectionManagerDeserializer _deserializer; + private ContainerInfo _rootImportedFolder; + private const string ExpectedRootFolderName = "test_puttyConnectionManager_database"; + private const string ExpectedConnectionDisplayName = "my ssh connection"; + private const string ExpectedConnectionHostname = "server1.mydomain.com"; + private const string ExpectedConnectionDescription = "My Description Here"; + private const int ExpectedConnectionPort = 22; + private const ProtocolType ExpectedProtocolType = ProtocolType.SSH2; + private const string ExpectedPuttySession = "MyCustomPuttySession"; + private const string ExpectedConnectionUsername = "mysshusername"; + private const string ExpectedConnectionPassword = "password123"; + + + [OneTimeSetUp] + public void OnetimeSetup() + { + var fileContents = Resources.test_puttyConnectionManager_database; + _deserializer = new PuttyConnectionManagerDeserializer(fileContents); + var connectionTreeModel = _deserializer.Deserialize(); + var rootNode = connectionTreeModel.RootNodes.First(); + _rootImportedFolder = rootNode.Children.Cast().First(); + } + + [OneTimeTearDown] + public void OnetimeTeardown() + { + _deserializer = null; + _rootImportedFolder = null; + } + + [Test] + public void RootFolderImportedWithCorrectName() + { + Assert.That(_rootImportedFolder.Name, Is.EqualTo(ExpectedRootFolderName)); + } + + [Test] + public void ConnectionDisplayNameImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Name, Is.EqualTo(ExpectedConnectionDisplayName)); + } + + [Test] + public void ConnectionHostNameImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Hostname, Is.EqualTo(ExpectedConnectionHostname)); + } + + [Test] + public void ConnectionDescriptionImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Description, Is.EqualTo(ExpectedConnectionDescription)); + } + + [Test] + public void ConnectionPortImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Port, Is.EqualTo(ExpectedConnectionPort)); + } + + [Test] + public void ConnectionProtocolTypeImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Protocol, Is.EqualTo(ExpectedProtocolType)); + } + + [Test] + public void ConnectionPuttySessionImported() + { + var connection = GetSshConnection(); + Assert.That(connection.PuttySession, Is.EqualTo(ExpectedPuttySession)); + } + + [Test] + public void ConnectionUsernameImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Username, Is.EqualTo(ExpectedConnectionUsername)); + } + + [Test] + public void ConnectionPasswordImported() + { + var connection = GetSshConnection(); + Assert.That(connection.Password, Is.EqualTo(ExpectedConnectionPassword)); + } + + private ConnectionInfo GetSshConnection() + { + var sshFolder = _rootImportedFolder.Children.OfType().First(node => node.Name == "SSHFolder"); + return sshFolder.Children.First(); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionDeserializerTests.cs new file mode 100644 index 000000000..1e77602e7 --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionDeserializerTests.cs @@ -0,0 +1,185 @@ +using System; +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Tree; +using mRemoteNGTests.Properties; +using NUnit.Framework; + + +namespace mRemoteNGTests.Config.Serializers +{ + public class RemoteDesktopConnectionDeserializerTests + { + // .rdp file schema: https://technet.microsoft.com/en-us/library/ff393699(v=ws.10).aspx + private string[] _connectionFileContents; + private RemoteDesktopConnectionDeserializer _deserializer; + private ConnectionTreeModel _connectionTreeModel; + private const string ExpectedHostname = "testhostname.domain.com"; + private const string ExpectedUserName = "myusernamehere"; + private const string ExpectedDomain = "myspecialdomain"; + private const string ExpectedGatewayHostname = "gatewayhostname.domain.com"; + private const int ExpectedPort = 9933; + private const ProtocolRDP.RDPColors ExpectedColors = ProtocolRDP.RDPColors.Colors24Bit; + private const bool ExpectedBitmapCaching = false; + private const ProtocolRDP.RDPResolutions ExpectedResolutionMode = ProtocolRDP.RDPResolutions.FitToWindow; + private const bool ExpectedWallpaperDisplay = true; + private const bool ExpectedThemesDisplay = true; + private const bool ExpectedFontSmoothing = true; + private const bool ExpectedDesktopComposition = true; + private const bool ExpectedSmartcardRedirection = true; + private const bool ExpectedDriveRedirection = true; + private const bool ExpectedPortRedirection = true; + private const bool ExpectedPrinterRedirection = true; + private const ProtocolRDP.RDPSounds ExpectedSoundRedirection = ProtocolRDP.RDPSounds.BringToThisComputer; + + + [OneTimeSetUp] + public void OnetimeSetup() + { + _connectionFileContents = Resources.test_remotedesktopconnection_rdp.Split(Environment.NewLine.ToCharArray()); + _deserializer = new RemoteDesktopConnectionDeserializer(_connectionFileContents); + _connectionTreeModel = _deserializer.Deserialize(); + } + + [OneTimeTearDown] + public void OnetimeTeardown() + { + _deserializer = null; + } + + [Test] + public void ConnectionTreeModelHasARootNode() + { + var numberOfRootNodes = _connectionTreeModel.RootNodes.Count; + Assert.That(numberOfRootNodes, Is.GreaterThan(0)); + } + + [Test] + public void RootNodeHasConnectionInfo() + { + var rootNodeContents = _connectionTreeModel.RootNodes.First().Children.OfType(); + Assert.That(rootNodeContents, Is.Not.Empty); + } + + [Test] + public void HostnameImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Hostname, Is.EqualTo(ExpectedHostname)); + } + + [Test] + public void PortImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Port, Is.EqualTo(ExpectedPort)); + } + + [Test] + public void UsernameImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Username, Is.EqualTo(ExpectedUserName)); + } + + [Test] + public void DomainImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Domain, Is.EqualTo(ExpectedDomain)); + } + + [Test] + public void RdpColorsImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Colors, Is.EqualTo(ExpectedColors)); + } + + [Test] + public void BitmapCachingImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.CacheBitmaps, Is.EqualTo(ExpectedBitmapCaching)); + } + + [Test] + public void ResolutionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.Resolution, Is.EqualTo(ExpectedResolutionMode)); + } + + [Test] + public void DisplayWallpaperImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.DisplayWallpaper, Is.EqualTo(ExpectedWallpaperDisplay)); + } + + [Test] + public void DisplayThemesImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.DisplayThemes, Is.EqualTo(ExpectedThemesDisplay)); + } + + [Test] + public void FontSmoothingImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.EnableFontSmoothing, Is.EqualTo(ExpectedFontSmoothing)); + } + + [Test] + public void DesktopCompositionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.EnableDesktopComposition, Is.EqualTo(ExpectedDesktopComposition)); + } + + [Test] + public void SmartcardRedirectionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.RedirectSmartCards, Is.EqualTo(ExpectedSmartcardRedirection)); + } + + [Test] + public void DriveRedirectionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.RedirectDiskDrives, Is.EqualTo(ExpectedDriveRedirection)); + } + + [Test] + public void PortRedirectionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.RedirectPorts, Is.EqualTo(ExpectedPortRedirection)); + } + + [Test] + public void PrinterRedirectionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.RedirectPrinters, Is.EqualTo(ExpectedPrinterRedirection)); + } + + [Test] + public void SoundRedirectionImportedCorrectly() + { + var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + Assert.That(connectionInfo.RedirectSound, Is.EqualTo(ExpectedSoundRedirection)); + } + + //[Test] + //public void GatewayHostnameImportedCorrectly() + //{ + // var connectionInfo = _connectionTreeModel.RootNodes.First().Children.First(); + // Assert.That(connectionInfo.RDGatewayHostname, Is.EqualTo(_expectedGatewayHostname)); + //} + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionManagerDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionManagerDeserializerTests.cs new file mode 100644 index 000000000..dd483ffbb --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/RemoteDesktopConnectionManagerDeserializerTests.cs @@ -0,0 +1,335 @@ +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNGTests.Properties; +using NUnit.Framework; +using System.IO; + +namespace mRemoteNGTests.Config.Serializers +{ + public class RemoteDesktopConnectionManagerDeserializerTests + { + private string _connectionFileContents; + private RemoteDesktopConnectionManagerDeserializer _deserializer; + private ConnectionTreeModel _connectionTreeModel; + private const string ExpectedName = "server1_displayname"; + private const string ExpectedHostname = "server1"; + private const string ExpectedDescription = "Comment text here"; + private const string ExpectedUsername = "myusername1"; + private const string ExpectedDomain = "mydomain"; + private const string ExpectedPassword = "passwordHere!"; + private const bool ExpectedUseConsoleSession = true; + private const int ExpectedPort = 9933; + private const ProtocolRDP.RDGatewayUsageMethod ExpectedGatewayUsageMethod = ProtocolRDP.RDGatewayUsageMethod.Always; + private const string ExpectedGatewayHostname = "gatewayserverhost.innerdomain.net"; + private const string ExpectedGatewayUsername = "gatewayusername"; + private const string ExpectedGatewayDomain = "innerdomain"; + private const string ExpectedGatewayPassword = "gatewayPassword123"; + private const ProtocolRDP.RDPResolutions ExpectedRdpResolution = ProtocolRDP.RDPResolutions.FitToWindow; + private const ProtocolRDP.RDPColors ExpectedRdpColorDepth = ProtocolRDP.RDPColors.Colors24Bit; + private const ProtocolRDP.RDPSounds ExpectedAudioRedirection = ProtocolRDP.RDPSounds.DoNotPlay; + private const bool ExpectedKeyRedirection = true; + private const bool ExpectedSmartcardRedirection = true; + private const bool ExpectedDriveRedirection = true; + private const bool ExpectedPortRedirection = true; + private const bool ExpectedPrinterRedirection = true; + private const ProtocolRDP.AuthenticationLevel ExpectedAuthLevel = ProtocolRDP.AuthenticationLevel.AuthRequired; + + + [OneTimeSetUp] + public void OnetimeSetup() + { + _connectionFileContents = Resources.test_rdcman_v2_2_schema1; + _deserializer = new RemoteDesktopConnectionManagerDeserializer(_connectionFileContents); + _connectionTreeModel = _deserializer.Deserialize(); + } + + [OneTimeTearDown] + public void OnetimeTeardown() + { + _deserializer = null; + } + + [Test] + public void ConnectionTreeModelHasARootNode() + { + var numberOfRootNodes = _connectionTreeModel.RootNodes.Count; + Assert.That(numberOfRootNodes, Is.GreaterThan(0)); + } + + [Test] + public void RootNodeHasContents() + { + var rootNodeContents = _connectionTreeModel.RootNodes.First().Children; + Assert.That(rootNodeContents, Is.Not.Empty); + } + + [Test] + public void AllSubRootFoldersImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var rootNodeContents = importedRdcmanRootNode.Children.Count(node => node.Name == "Group1" || node.Name == "Group2"); + Assert.That(rootNodeContents, Is.EqualTo(2)); + } + + [Test] + public void ConnectionDisplayNameImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Name, Is.EqualTo(ExpectedName)); + } + + [Test] + public void ConnectionHostnameImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Hostname, Is.EqualTo(ExpectedHostname)); + } + + [Test] + public void ConnectionDescriptionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Description, Is.EqualTo(ExpectedDescription)); + } + + [Test] + public void ConnectionUsernameImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Username, Is.EqualTo(ExpectedUsername)); + } + + [Test] + public void ConnectionDomainImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Domain, Is.EqualTo(ExpectedDomain)); + } + + // Since password is encrypted with a machine key, cant test decryption on another machine + //[Test] + //public void ConnectionPasswordImported() + //{ + // var rootNode = _connectionTreeModel.RootNodes.First(); + // var importedRdcmanRootNode = rootNode.Children.OfType().First(); + // var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + // var connection = group1.Children.First(); + // Assert.That(connection.Password, Is.EqualTo(ExpectedPassword)); + //} + + [Test] + public void ConnectionProtocolSetToRdp() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Protocol, Is.EqualTo(ProtocolType.RDP)); + } + + [Test] + public void ConnectionUseConsoleSessionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.UseConsoleSession, Is.EqualTo(ExpectedUseConsoleSession)); + } + + [Test] + public void ConnectionPortImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Port, Is.EqualTo(ExpectedPort)); + } + + [Test] + public void ConnectionGatewayUsageMethodImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RDGatewayUsageMethod, Is.EqualTo(ExpectedGatewayUsageMethod)); + } + + [Test] + public void ConnectionGatewayHostnameImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RDGatewayHostname, Is.EqualTo(ExpectedGatewayHostname)); + } + + [Test] + public void ConnectionGatewayUsernameImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RDGatewayUsername, Is.EqualTo(ExpectedGatewayUsername)); + } + + // Since password is encrypted with a machine key, cant test decryption on another machine + //[Test] + //public void ConnectionGatewayPasswordImported() + //{ + // var rootNode = _connectionTreeModel.RootNodes.First(); + // var importedRdcmanRootNode = rootNode.Children.OfType().First(); + // var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + // var connection = group1.Children.First(); + // Assert.That(connection.RDGatewayPassword, Is.EqualTo(ExpectedGatewayPassword)); + //} + + [Test] + public void ConnectionGatewayDomainImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RDGatewayDomain, Is.EqualTo(ExpectedGatewayDomain)); + } + + [Test] + public void ConnectionResolutionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Resolution, Is.EqualTo(ExpectedRdpResolution)); + } + + [Test] + public void ConnectionColorDepthImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.Colors, Is.EqualTo(ExpectedRdpColorDepth)); + } + + [Test] + public void ConnectionAudioRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectSound, Is.EqualTo(ExpectedAudioRedirection)); + } + + [Test] + public void ConnectionKeyRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectKeys, Is.EqualTo(ExpectedKeyRedirection)); + } + + [Test] + public void ConnectionDriveRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectDiskDrives, Is.EqualTo(ExpectedDriveRedirection)); + } + + [Test] + public void ConnectionPortRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectPorts, Is.EqualTo(ExpectedPortRedirection)); + } + + [Test] + public void ConnectionPrinterRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectPrinters, Is.EqualTo(ExpectedPrinterRedirection)); + } + + [Test] + public void ConnectionSmartcardRedirectionImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RedirectSmartCards, Is.EqualTo(ExpectedSmartcardRedirection)); + } + + [Test] + public void ConnectionauthenticationLevelImported() + { + var rootNode = _connectionTreeModel.RootNodes.First(); + var importedRdcmanRootNode = rootNode.Children.OfType().First(); + var group1 = importedRdcmanRootNode.Children.OfType().First(node => node.Name == "Group1"); + var connection = group1.Children.First(); + Assert.That(connection.RDPAuthenticationLevel, Is.EqualTo(ExpectedAuthLevel)); + } + + [Test] + public void ExceptionThrownOnBadSchemaVersion() + { + var badFileContents = Resources.test_rdcman_v2_2_badschemaversion; + var deserializer = new RemoteDesktopConnectionManagerDeserializer(badFileContents); + Assert.That(() => deserializer.Deserialize(), Throws.TypeOf()); + } + + [Test] + public void ExceptionThrownOnUnsupportedVersion() + { + var badFileContents = Resources.test_rdcman_badVersionNumber; + var deserializer = new RemoteDesktopConnectionManagerDeserializer(badFileContents); + Assert.That(() => deserializer.Deserialize(), Throws.TypeOf()); + } + + [Test] + public void ExceptionThrownOnNoVersion() + { + var badFileContents = Resources.test_rdcman_noversion; + var deserializer = new RemoteDesktopConnectionManagerDeserializer(badFileContents); + Assert.That(() => deserializer.Deserialize(), Throws.TypeOf()); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs new file mode 100644 index 000000000..68e29239f --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsDeserializerTests.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNGTests.Properties; +using NUnit.Framework; + +namespace mRemoteNGTests.Config.Serializers +{ + public class XmlConnectionsDeserializerTests + { + private XmlConnectionsDeserializer _xmlConnectionsDeserializer; + private ConnectionTreeModel _connectionTreeModel; + + [SetUp] + public void Setup() + { + _xmlConnectionsDeserializer = new XmlConnectionsDeserializer(Resources.TestConfCons); + _connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(); + } + + [TearDown] + public void Teardown() + { + _xmlConnectionsDeserializer = null; + _connectionTreeModel = null; + } + + [Test] + public void DeserializingCreatesRootNode() + { + Assert.That(_connectionTreeModel.RootNodes, Is.Not.Empty); + } + + [Test] + public void RootNodeHasThreeChildren() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + Assert.That(connectionRoot.Children.Count, Is.EqualTo(3)); + } + + [Test] + public void RootContainsFolder1() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + Assert.That(ContainsNodeNamed("Folder1", connectionRoot.Children), Is.True); + } + + [Test] + public void Folder1ContainsThreeConnections() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + var folder1 = GetFolderNamed("Folder1", connectionRoot.Children); + var folder1ConnectionCount = folder1?.Children.Count(node => !(node is ContainerInfo)); + Assert.That(folder1ConnectionCount, Is.EqualTo(3)); + } + + [Test] + public void Folder2ContainsThreeNodes() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + var folder2 = GetFolderNamed("Folder2", connectionRoot.Children); + var folder1Count = folder2?.Children.Count(); + Assert.That(folder1Count, Is.EqualTo(3)); + } + + [Test] + public void Folder21HasTwoNodes() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + var folder2 = GetFolderNamed("Folder2", connectionRoot.Children); + var folder21 = GetFolderNamed("Folder2.1", folder2.Children); + Assert.That(folder21.Children.Count, Is.EqualTo(2)); + } + + [Test] + public void Folder211HasOneConnection() + { + var connectionRoot = _connectionTreeModel.RootNodes[0]; + var folder2 = GetFolderNamed("Folder2", connectionRoot.Children); + var folder21 = GetFolderNamed("Folder2.1", folder2.Children); + var folder211 = GetFolderNamed("Folder2.1.1", folder21.Children); + var connectionCount = folder211.Children.Count(node => !(node is ContainerInfo)); + Assert.That(connectionCount, Is.EqualTo(1)); + } + + private bool ContainsNodeNamed(string name, IEnumerable list) + { + return list.Any(node => node.Name == name); + } + + private ContainerInfo GetFolderNamed(string name, IEnumerable list) + { + var folder = list.First(node => (node is ContainerInfo && node.Name == name)) as ContainerInfo; + return folder; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Connection/AbstractConnectionInfoDataTests.cs b/mRemoteNGTests/Connection/AbstractConnectionInfoDataTests.cs new file mode 100644 index 000000000..8d2ef51fe --- /dev/null +++ b/mRemoteNGTests/Connection/AbstractConnectionInfoDataTests.cs @@ -0,0 +1,507 @@ +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.Http; +using mRemoteNG.Connection.Protocol.ICA; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Connection.Protocol.VNC; +using NUnit.Framework; + + +namespace mRemoteNGTests.Connection +{ + public class AbstractConnectionInfoDataTests + { + private class TestAbstractConnectionInfoData : AbstractConnectionInfoData {} + private TestAbstractConnectionInfoData _testAbstractConnectionInfoData; + + [SetUp] + public void Setup() + { + _testAbstractConnectionInfoData = new TestAbstractConnectionInfoData(); + } + + [TearDown] + public void Teardown() + { + _testAbstractConnectionInfoData = null; + } + + + [Test] + public void NameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Name = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void DescriptionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Description = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void IconNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Icon = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PanelNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Panel = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void HostnameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Hostname = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void UsernameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Username = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PasswordNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Password = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void DomainNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Domain = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ProtocolNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Protocol = ProtocolType.HTTP; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ExtAppNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.ExtApp = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PortNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Port = 9999; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PuttySessionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.PuttySession = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void IcaEncryptionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.ICAEncryptionStrength = ProtocolICA.EncryptionStrength.Encr128BitLogonOnly; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void UseConsoleSessionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.UseConsoleSession = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdpAuthenticationLevelNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.AuthRequired; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void LoadBalanceInfoNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.LoadBalanceInfo = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RenderingEngineNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RenderingEngine = HTTPBase.RenderingEngine.Gecko; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void UseCredSspNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.UseCredSsp = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayUsageMethodNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayUsageMethod = ProtocolRDP.RDGatewayUsageMethod.Always; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayHostnameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayHostname = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayUseConnectionCredentialsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayUseConnectionCredentials = ProtocolRDP.RDGatewayUseConnectionCredentials.SmartCard; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayUsernameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayUsername = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayPasswordNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayPassword = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RdGatewayDomainNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RDGatewayDomain = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ResolutionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Resolution = ProtocolRDP.RDPResolutions.Res1366x768; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void AutomaticResizeNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.AutomaticResize = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ColorsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.Colors = ProtocolRDP.RDPColors.Colors16Bit; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void CacheBitmapsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.CacheBitmaps = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void DisplayWallpaperNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.DisplayWallpaper = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void DisplayThemesNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.DisplayThemes = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void EnableFontSmoothingNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.EnableFontSmoothing = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void EnableDesktopCompositionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.EnableDesktopComposition = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectKeysNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectKeys = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectDiskDrivesNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectDiskDrives = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectPrintersNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectPrinters = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectPortsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectPorts = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectSmartCardsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectSmartCards = true; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RedirectSoundNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.RedirectSound = ProtocolRDP.RDPSounds.DoNotPlay; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PreExtAppNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.PreExtApp = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void PostExtAppNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.PostExtApp = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void MacAddressNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.MacAddress = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void UserFieldNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.UserField = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncCompressionNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCCompression = ProtocolVNC.Compression.Comp5; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncEncodingNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCEncoding = ProtocolVNC.Encoding.EncTight; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncAuthModeNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCAuthMode = ProtocolVNC.AuthMode.AuthWin; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncProxyTypeNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCProxyType = ProtocolVNC.ProxyType.ProxyUltra; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncProxyIpNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCProxyIP = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncProxyPortNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCProxyPort = 9999; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncProxyUsernameNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCProxyUsername = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncProxyPasswordNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCProxyPassword = "a"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncColorsNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCColors = ProtocolVNC.Colors.Col8Bit; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncSmartSizeModeNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCSmartSizeMode = ProtocolVNC.SmartSizeMode.SmartSFree; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void VncViewOnlyNotifiesOnValueChange() + { + var wasCalled = false; + _testAbstractConnectionInfoData.PropertyChanged += (sender, args) => wasCalled = true; + _testAbstractConnectionInfoData.VNCViewOnly = true; + Assert.That(wasCalled, Is.True); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Connection/ConnectionInfoComparerTests.cs b/mRemoteNGTests/Connection/ConnectionInfoComparerTests.cs new file mode 100644 index 000000000..73df486d9 --- /dev/null +++ b/mRemoteNGTests/Connection/ConnectionInfoComparerTests.cs @@ -0,0 +1,42 @@ +using System.ComponentModel; +using mRemoteNG.Connection; +using NUnit.Framework; + + +namespace mRemoteNGTests.Connection +{ + public class ConnectionInfoComparerTests + { + private ConnectionInfo _con1; + private ConnectionInfo _con2; + + [OneTimeSetUp] + public void OnetimeSetup() + { + _con1 = new ConnectionInfo { Name = "a" }; + _con2 = new ConnectionInfo { Name = "b" }; + } + + [Test] + public void SortAscendingOnName() + { + var comparer = new ConnectionInfoComparer(node => node.Name) + { + SortDirection = ListSortDirection.Ascending + }; + var compareReturn = comparer.Compare(_con1, _con2); + Assert.That(compareReturn, Is.Negative); + } + + [Test] + public void SortDescendingOnName() + { + var comparer = new ConnectionInfoComparer(node => node.Name) + { + SortDirection = ListSortDirection.Descending + }; + var compareReturn = comparer.Compare(_con1, _con2); + Assert.That(compareReturn, Is.Positive); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Connection/ConnectionInfoTests.cs b/mRemoteNGTests/Connection/ConnectionInfoTests.cs index ea1cce0fe..b3f80c680 100644 --- a/mRemoteNGTests/Connection/ConnectionInfoTests.cs +++ b/mRemoteNGTests/Connection/ConnectionInfoTests.cs @@ -42,7 +42,7 @@ namespace mRemoteNGTests.Connection public void CopyCreatesMemberwiseCopy() { _connectionInfo.Domain = TestDomain; - var secondConnection = _connectionInfo.Copy(); + var secondConnection = _connectionInfo.Clone(); Assert.That(secondConnection.Domain, Is.EqualTo(_connectionInfo.Domain)); } diff --git a/mRemoteNGTests/Container/ContainerInfoTests.cs b/mRemoteNGTests/Container/ContainerInfoTests.cs index 528991067..94ee11d80 100644 --- a/mRemoteNGTests/Container/ContainerInfoTests.cs +++ b/mRemoteNGTests/Container/ContainerInfoTests.cs @@ -8,77 +8,228 @@ namespace mRemoteNGTests.Container public class ContainerInfoTests { private ContainerInfo _containerInfo; - private ConnectionInfo _connectionInfo; + private ConnectionInfo _con1; + private ConnectionInfo _con2; + private ConnectionInfo _con3; [SetUp] public void Setup() { _containerInfo = new ContainerInfo(); - _connectionInfo = new ConnectionInfo(); + _con1 = new ConnectionInfo {Name = "a"}; + _con2 = new ConnectionInfo {Name = "b"}; + _con3 = new ConnectionInfo {Name = "c"}; } [TearDown] public void Teardown() { _containerInfo = null; - _connectionInfo = null; + _con1 = null; + _con2 = null; + _con3 = null; } [Test] public void AddSetsParentPropertyOnTheChild() { - _containerInfo.Add(_connectionInfo); - Assert.That(_connectionInfo.Parent, Is.EqualTo(_containerInfo)); + _containerInfo.AddChild(_con1); + Assert.That(_con1.Parent, Is.EqualTo(_containerInfo)); } [Test] public void AddAddsChildToChildrenList() { - _containerInfo.Add(_connectionInfo); - Assert.That(_containerInfo.Children, Does.Contain(_connectionInfo)); + _containerInfo.AddChild(_con1); + Assert.That(_containerInfo.Children, Does.Contain(_con1)); } [Test] public void AddRangeAddsAllItems() { - var collection = new[] {new ConnectionInfo(),new ConnectionInfo(), new ContainerInfo()}; - _containerInfo.AddRange(collection); + var collection = new[] { _con1, _con2, _con3 }; + _containerInfo.AddChildRange(collection); Assert.That(_containerInfo.Children, Is.EquivalentTo(collection)); } [Test] public void RemoveUnsetsParentPropertyOnChild() { - _containerInfo.Add(_connectionInfo); - _containerInfo.Remove(_connectionInfo); - Assert.That(_connectionInfo.Parent, Is.Not.EqualTo(_containerInfo)); + _containerInfo.AddChild(_con1); + _containerInfo.RemoveChild(_con1); + Assert.That(_con1.Parent, Is.Not.EqualTo(_containerInfo)); } [Test] public void RemoveRemovesChildFromChildrenList() { - _containerInfo.Add(_connectionInfo); - _containerInfo.Remove(_connectionInfo); - Assert.That(_containerInfo.Children, Does.Not.Contains(_connectionInfo)); + _containerInfo.AddChild(_con1); + _containerInfo.RemoveChild(_con1); + Assert.That(_containerInfo.Children, Does.Not.Contains(_con1)); } [Test] public void RemoveRangeRemovesAllIndicatedItems() { - var collection = new[] { new ConnectionInfo(), new ConnectionInfo(), new ContainerInfo() }; - _containerInfo.AddRange(collection); - _containerInfo.RemoveRange(collection); + var collection = new[] { _con1, _con2, new ContainerInfo() }; + _containerInfo.AddChildRange(collection); + _containerInfo.RemoveChildRange(collection); Assert.That(_containerInfo.Children, Does.Not.Contains(collection[0]).And.Not.Contains(collection[1]).And.Not.Contains(collection[2])); } [Test] public void RemoveRangeDoesNotRemoveUntargetedMembers() { - var collection = new[] { new ConnectionInfo(), new ConnectionInfo(), new ContainerInfo() }; - _containerInfo.AddRange(collection); - _containerInfo.Add(_connectionInfo); - _containerInfo.RemoveRange(collection); - Assert.That(_containerInfo.Children, Does.Contain(_connectionInfo)); + var collection = new[] { _con1, _con2, new ContainerInfo() }; + _containerInfo.AddChildRange(collection); + _containerInfo.AddChild(_con3); + _containerInfo.RemoveChildRange(collection); + Assert.That(_containerInfo.Children, Does.Contain(_con3)); + } + + [Test] + public void AddingChildTriggersCollectionChangedEvent() + { + var wasCalled = false; + _containerInfo.CollectionChanged += (sender, args) => wasCalled = true; + _containerInfo.AddChild(_con1); + Assert.That(wasCalled, Is.True); + } + + [Test] + public void RemovingChildTriggersCollectionChangedEvent() + { + var wasCalled = false; + _containerInfo.AddChild(_con1); + _containerInfo.CollectionChanged += (sender, args) => wasCalled = true; + _containerInfo.RemoveChild(_con1); + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ChangingChildPropertyTriggersPropertyChangedEvent() + { + var wasCalled = false; + _containerInfo.AddChild(_con1); + _containerInfo.PropertyChanged += (sender, args) => wasCalled = true; + _con1.Name = "somethinghere"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void ChangingSubChildPropertyTriggersPropertyChangedEvent() + { + var wasCalled = false; + var container2 = new ContainerInfo(); + _containerInfo.AddChild(container2); + container2.AddChild(_con1); + _containerInfo.PropertyChanged += (sender, args) => wasCalled = true; + _con1.Name = "somethinghere"; + Assert.That(wasCalled, Is.True); + } + + [Test] + public void SetChildPositionPutsChildInCorrectPosition() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + _containerInfo.SetChildPosition(_con2, 2); + Assert.That(_containerInfo.Children.IndexOf(_con2), Is.EqualTo(2)); + } + + [Test] + public void SettingChildPositionAboveArrayBoundsPutsItAtEndOfList() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var finalIndex = _containerInfo.Children.Count - 1; + _containerInfo.SetChildPosition(_con2, 5); + Assert.That(_containerInfo.Children.IndexOf(_con2), Is.EqualTo(finalIndex)); + } + + [Test] + public void SettingChildPositionBelowArrayBoundsDoesNotMoveTheChild() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var originalIndex = _containerInfo.Children.IndexOf(_con2); + _containerInfo.SetChildPosition(_con2, -1); + Assert.That(_containerInfo.Children.IndexOf(_con2), Is.EqualTo(originalIndex)); + } + + [Test] + public void SetChildAbovePutsChildInCorrectPosition() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var referenceChildIndexBeforeMove = _containerInfo.Children.IndexOf(_con2); + _containerInfo.SetChildAbove(_con3, _con2); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con3); + Assert.That(targetsNewIndex, Is.EqualTo(referenceChildIndexBeforeMove)); + } + + [Test] + public void SetChildBelowPutsChildInCorrectPosition() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var referenceChildIndexBeforeMove = _containerInfo.Children.IndexOf(_con1); + _containerInfo.SetChildBelow(_con3, _con1); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con3); + Assert.That(targetsNewIndex, Is.EqualTo(referenceChildIndexBeforeMove+1)); + } + + [Test] + public void PromoteChildMovesTargetUpOne() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var targetsIndexBeforeMove = _containerInfo.Children.IndexOf(_con3); + _containerInfo.PromoteChild(_con3); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con3); + Assert.That(targetsNewIndex, Is.EqualTo(targetsIndexBeforeMove - 1)); + } + + [Test] + public void PromoteChildDoesNothingWhenAlreadyAtTopOfList() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var targetsIndexBeforeMove = _containerInfo.Children.IndexOf(_con1); + _containerInfo.PromoteChild(_con1); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con1); + Assert.That(targetsNewIndex, Is.EqualTo(targetsIndexBeforeMove)); + } + + [Test] + public void DemoteChildMovesTargetDownOne() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var targetsIndexBeforeMove = _containerInfo.Children.IndexOf(_con1); + _containerInfo.DemoteChild(_con1); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con1); + Assert.That(targetsNewIndex, Is.EqualTo(targetsIndexBeforeMove + 1)); + } + + [Test] + public void DemoteChildDoesNothingWhenAlreadyAtTopOfList() + { + _containerInfo.AddChild(_con1); + _containerInfo.AddChild(_con2); + _containerInfo.AddChild(_con3); + var targetsIndexBeforeMove = _containerInfo.Children.IndexOf(_con3); + _containerInfo.DemoteChild(_con3); + var targetsNewIndex = _containerInfo.Children.IndexOf(_con3); + Assert.That(targetsNewIndex, Is.EqualTo(targetsIndexBeforeMove)); } } } \ No newline at end of file diff --git a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs index 8169f6faf..c5645473b 100644 --- a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs +++ b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs @@ -39,9 +39,9 @@ namespace mRemoteNGTests.IntegrationTests var connection1 = new ConnectionInfo(); var connection2 = new ConnectionInfo(); var connection3 = new ConnectionInfo {Inheritance = {Username = true}}; - _rootNode.Add(folder1); - folder1.AddRange(new []{connection1, folder2, connection3}); - folder2.Add(connection2); + _rootNode.AddChild(folder1); + folder1.AddChildRange(new []{connection1, folder2, connection3}); + folder2.AddChild(connection2); Assert.That(connection3.Username, Is.EqualTo(folder1.Username)); } @@ -50,8 +50,8 @@ namespace mRemoteNGTests.IntegrationTests { var folder = new ContainerInfo() {Protocol = ProtocolType.SSH2, Username = "folderUser", Domain = "CoolDomain"}; var connection = new ConnectionInfo() {Inheritance = {EverythingInherited = true}}; - _rootNode.Add(folder); - folder.Add(connection); + _rootNode.AddChild(folder); + folder.AddChild(connection); Assert.That(new object[] { connection.Protocol, connection.Username, connection.Domain }, Is.EquivalentTo(new object[] {folder.Protocol, folder.Username, folder.Domain})); } @@ -62,10 +62,10 @@ namespace mRemoteNGTests.IntegrationTests var folder2 = new ContainerInfo {Inheritance = {Username = true}}; var folder3 = new ContainerInfo {Inheritance = {Username = true}}; var connection = new ConnectionInfo {Inheritance = {Username = true}}; - _rootNode.Add(folder1); - folder1.Add(folder2); - folder2.Add(folder3); - folder3.Add(connection); + _rootNode.AddChild(folder1); + folder1.AddChild(folder2); + folder2.AddChild(folder3); + folder3.AddChild(connection); Assert.That(connection.Username, Is.EqualTo(folder1.Username)); } } diff --git a/mRemoteNGTests/Properties/Resources.Designer.cs b/mRemoteNGTests/Properties/Resources.Designer.cs new file mode 100644 index 000000000..8413fd1a7 --- /dev/null +++ b/mRemoteNGTests/Properties/Resources.Designer.cs @@ -0,0 +1,218 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace mRemoteNGTests.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mRemoteNGTests.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to RmV7zw/a7ZRRzZdcTkrLDgBfyEmeh8OFMgg2OKFJnwg=. + /// + internal static string legacyrijndael_ciphertext { + get { + return ResourceManager.GetString("legacyrijndael_ciphertext", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-16"?> + ///<!-- ****************************************************************--> + ///<!-- * *--> + ///<!-- * PuTTY Configuration Manager save file - All right reserved. *--> + ///<!-- * *--> + ///<!-- ****************************************************************--> + ///<!-- The following lines can be modified at your own risks. --> + ///<configuration version="0.7.1.136" [rest of string was truncated]";. + /// + internal static string test_puttyConnectionManager_database { + get { + return ResourceManager.GetString("test_puttyConnectionManager_database", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<RDCMan schemaVersion="1"> + /// <version>99.99</version> + /// <file> + /// </file> + ///</RDCMan>. + /// + internal static string test_rdcman_badVersionNumber { + get { + return ResourceManager.GetString("test_rdcman_badVersionNumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<RDCMan schemaVersion="1"> + /// <file> + /// </file> + ///</RDCMan>. + /// + internal static string test_rdcman_noversion { + get { + return ResourceManager.GetString("test_rdcman_noversion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<RDCMan schemaVersion="-99"> + /// <version>2.2</version> + /// <file> + /// </file> + ///</RDCMan>. + /// + internal static string test_rdcman_v2_2_badschemaversion { + get { + return ResourceManager.GetString("test_rdcman_v2_2_badschemaversion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<RDCMan schemaVersion="1"> + /// <version>2.2</version> + /// <file> + /// <properties> + /// <name>test_rdcman_v2_2_schema1</name> + /// <expanded>True</expanded> + /// <comment /> + /// <logonCredentials inherit="FromParent" /> + /// <connectionSettings inherit="FromParent" /> + /// <gatewaySettings inherit="FromParent" /> + /// <remoteDesktop inherit="FromParent" /> + /// <localResources inherit="FromParent" [rest of string was truncated]";. + /// + internal static string test_rdcman_v2_2_schema1 { + get { + return ResourceManager.GetString("test_rdcman_v2_2_schema1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<RDCMan programVersion="2.7" schemaVersion="3"> + /// <file> + /// <credentialsProfiles /> + /// <properties> + /// <expanded>True</expanded> + /// <name>test_RDCMan_connections</name> + /// </properties> + /// <smartGroup> + /// <properties> + /// <expanded>False</expanded> + /// <name>AllServers</name> + /// </properties> + /// <ruleGroup operator="All"> + /// <rule> + /// <property>DisplayName</property> + /// <operator>Matches</operator> + /// [rest of string was truncated]";. + /// + internal static string test_rdcman_v2_7_schema3 { + get { + return ResourceManager.GetString("test_rdcman_v2_7_schema3", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to screen mode id:i:1 + ///use multimon:i:0 + ///desktopwidth:i:800 + ///desktopheight:i:600 + ///session bpp:i:24 + ///winposstr:s:0,3,0,0,800,600 + ///compression:i:1 + ///keyboardhook:i:2 + ///audiocapturemode:i:0 + ///videoplaybackmode:i:1 + ///connection type:i:7 + ///networkautodetect:i:1 + ///bandwidthautodetect:i:1 + ///displayconnectionbar:i:1 + ///username:s:myusernamehere + ///enableworkspacereconnect:i:0 + ///disable wallpaper:i:1 + ///allow font smoothing:i:1 + ///allow desktop composition:i:1 + ///disable full window drag:i:1 + ///disable menu anims:i:1 + ///disable themes:i:1 + /// [rest of string was truncated]";. + /// + internal static string test_remotedesktopconnection_rdp { + get { + return ResourceManager.GetString("test_remotedesktopconnection_rdp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> + ///<Connections Name="Connections" Export="False" Protected="95syzRuZ4mRxpNkZQzoyX8SDpQXLyMq3GncO8o4SyTBoYvn3TAWgn05ZEU2DrjkM" ConfVersion="2.5"> + /// <Node Name="Folder1" Type="Container" Expanded="True" Descr="" Icon="mRemoteNG" Panel="General" Username="" Domain="" Password="" Hostname="" Protocol="ICA" PuttySession="Default Settings" Port="1494" ConnectToConsole="False" UseCredSsp="True" RenderingEngine="IE" ICAEncryptionStrength="Encr128Bit" RDPAuthenticationLevel=" [rest of string was truncated]";. + /// + internal static string TestConfCons { + get { + return ResourceManager.GetString("TestConfCons", resourceCulture); + } + } + } +} diff --git a/mRemoteNGTests/Properties/Resources.resx b/mRemoteNGTests/Properties/Resources.resx new file mode 100644 index 000000000..28e47a0cf --- /dev/null +++ b/mRemoteNGTests/Properties/Resources.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\legacyrijndael_ciphertext.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\TestConfCons.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\test_puttyConnectionManager_database.dat;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 + + + ..\Resources\test_rdcman_badVersionNumber.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\test_rdcman_noversion.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\test_rdcman_v2_2_badschemaversion.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\test_rdcman_v2_2_schema1.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\test_RDCMan_v2_7_schema3.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\test_remotedesktopconnection.rdp;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16 + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/TestConfCons.xml b/mRemoteNGTests/Resources/TestConfCons.xml new file mode 100644 index 000000000..22d6627c0 --- /dev/null +++ b/mRemoteNGTests/Resources/TestConfCons.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/legacyrijndael_ciphertext.txt b/mRemoteNGTests/Resources/legacyrijndael_ciphertext.txt new file mode 100644 index 000000000..3b9f5bece --- /dev/null +++ b/mRemoteNGTests/Resources/legacyrijndael_ciphertext.txt @@ -0,0 +1 @@ +RmV7zw/a7ZRRzZdcTkrLDgBfyEmeh8OFMgg2OKFJnwg= \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_puttyConnectionManager_database.dat b/mRemoteNGTests/Resources/test_puttyConnectionManager_database.dat new file mode 100644 index 000000000..552acdde5 Binary files /dev/null and b/mRemoteNGTests/Resources/test_puttyConnectionManager_database.dat differ diff --git a/mRemoteNGTests/Resources/test_puttyConnectionManager_database_backup.dat b/mRemoteNGTests/Resources/test_puttyConnectionManager_database_backup.dat new file mode 100644 index 000000000..a5496285e Binary files /dev/null and b/mRemoteNGTests/Resources/test_puttyConnectionManager_database_backup.dat differ diff --git a/mRemoteNGTests/Resources/test_rdcman_badVersionNumber.rdg b/mRemoteNGTests/Resources/test_rdcman_badVersionNumber.rdg new file mode 100644 index 000000000..4ba46544b --- /dev/null +++ b/mRemoteNGTests/Resources/test_rdcman_badVersionNumber.rdg @@ -0,0 +1,6 @@ + + + 99.99 + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_rdcman_noversion.rdg b/mRemoteNGTests/Resources/test_rdcman_noversion.rdg new file mode 100644 index 000000000..b5a0d65eb --- /dev/null +++ b/mRemoteNGTests/Resources/test_rdcman_noversion.rdg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_rdcman_v2_2_badschemaversion.rdg b/mRemoteNGTests/Resources/test_rdcman_v2_2_badschemaversion.rdg new file mode 100644 index 000000000..185cfc423 --- /dev/null +++ b/mRemoteNGTests/Resources/test_rdcman_v2_2_badschemaversion.rdg @@ -0,0 +1,6 @@ + + + 2.2 + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_rdcman_v2_2_schema1.rdg b/mRemoteNGTests/Resources/test_rdcman_v2_2_schema1.rdg new file mode 100644 index 000000000..74986a401 --- /dev/null +++ b/mRemoteNGTests/Resources/test_rdcman_v2_2_schema1.rdg @@ -0,0 +1,145 @@ + + + 2.2 + + + test_rdcman_v2_2_schema1 + True + + + + + + + + + + + + Group1 + True + + + + + + + + + + + server1 + server1_displayname + Comment text here + + myusername1 + mydomain + AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/jk3lWsW+ku0n4AOVYyLTAAAAAACAAAAAAAQZgAAAAEAACAAAABhmrmYHd+c7VjWfPvxJ8pgi55yeV2brJDV/i9XzGUz6wAAAAAOgAAAAAIAACAAAAACJMhtb6tmkJn9vSv9J4VMWgt3S7Ikmf63xK/uKQ+YuyAAAACD3mJOT1910KD71zqbi+m/F6A0LK0tu0BhpOhr9v0yH0AAAADrb+Uv2btNYhfTUDGbw5pT5dbp5oXzc3I8QO7X1vgMXiI5TkrSxfHP/2j+Yak++vAjpVtzlxk49hpDLNAZnnhg + + + True + + + 9933 + + + gatewayusername + innerdomain + AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/jk3lWsW+ku0n4AOVYyLTAAAAAACAAAAAAAQZgAAAAEAACAAAACgU917evQ54VsDf3nkofPOAPj0icRejg3yfyUwZqV3DgAAAAAOgAAAAAIAACAAAACuPdtJTxd2yvFuTpSOeZz1loraPu2WFqUXiJp4cfjbJTAAAAB8L5YX93h6pQoKJozrk+Y+spHWqP+eqBUXRJ45oLreKslslSWCEO7VWg4rgr0FYsNAAAAAU1i5aSTlBy99EkNEd2inrAJAopCfNig6osiEVdvA6eYnCogG5mhzYEK5d5Wt49S8HbEyuLF/8IxV0PKG53vCZQ== + True + gatewayserverhost.innerdomain.net + 4 + False + False + + + 1024 x 768 + True + False + 24 + + + 2 + 0 + 0 + 1 + True + True + True + True + True + + + 1 + + + 1 + + + + server2 + server2 + + + + + + + + + + + + + Group2 + True + + + + + + + + + + + + Group3 + True + + + + + + + + + + + server3 + server3 + + + + + + + + + + + server4 + server4 + + + + + + + + + + + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_rdcman_v2_7_schema3.rdg b/mRemoteNGTests/Resources/test_rdcman_v2_7_schema3.rdg new file mode 100644 index 000000000..e4b61c7c3 --- /dev/null +++ b/mRemoteNGTests/Resources/test_rdcman_v2_7_schema3.rdg @@ -0,0 +1,120 @@ + + + + + + True + test_RDCMan_connections + + + + False + AllServers + + + + DisplayName + Matches + server + + + + + + True + Group1 + + + + server1 + + + Custom + someusername1 + AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/jk3lWsW+ku0n4AOVYyLTAAAAAACAAAAAAAQZgAAAAEAACAAAACZryl2a4trJLcUdyg7jL/m51fxn4Vy+je6SBhT5FasmgAAAAAOgAAAAAIAACAAAAAcG6MQhKFvEcKRrRE74YKrrnYKxLFnVxbGzyfl7JoyvjAAAACAofcbQqcr6h9VQuwwWW5IBkW1zsugofl1MjsL9t2uWfuBgnrya1Xlyue5E7cG8BZAAAAApgx/XXqBqXhr6CV2SJTlXihg7n5epOIT02A8ymy3qRftDgXlmu3IaN7krK3gofv+iNdVrvIdJJMYCihm7dyqOw== + mydomain + + + False + + + 9933 + + + + True + gatewayserver.innerdomain.net + Any + True + True + Custom + + + + + + False + True + 24 + + + Client + Dynamic + DoNotRecord + FullScreenClient + True + True + + C:\ + D:\ + E:\ + F:\ + G:\ + + True + True + True + True + + + 1 + False + False + + + Warn + + + + + server2 + + + + + + True + Group2 + + + + True + Group3 + + + + server3 + + + + + server4 + + + + + + + + + \ No newline at end of file diff --git a/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp b/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp new file mode 100644 index 000000000..f144f9718 Binary files /dev/null and b/mRemoteNGTests/Resources/test_remotedesktopconnection.rdp differ diff --git a/mRemoteNGTests/Security/LegacyRijndaelCryptographyProviderTests.cs b/mRemoteNGTests/Security/LegacyRijndaelCryptographyProviderTests.cs index 6ae291199..f5ffbb604 100644 --- a/mRemoteNGTests/Security/LegacyRijndaelCryptographyProviderTests.cs +++ b/mRemoteNGTests/Security/LegacyRijndaelCryptographyProviderTests.cs @@ -1,17 +1,19 @@ using System.Security; using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNGTests.Properties; using NUnit.Framework; namespace mRemoteNGTests.Security { - [TestFixture()] public class LegacyRijndaelCryptographyProviderTests { private ICryptographyProvider _rijndaelCryptographyProvider; private SecureString _encryptionKey; private string _plainText; + private string _importedCipherText = Resources.legacyrijndael_ciphertext; + [SetUp] public void SetUp() @@ -55,5 +57,12 @@ namespace mRemoteNGTests.Security var cipherText2 = _rijndaelCryptographyProvider.Encrypt(_plainText, _encryptionKey); Assert.That(cipherText1, Is.Not.EqualTo(cipherText2)); } + + [Test] + public void DecryptingFromPreviousApplicationExecutionWorks() + { + var decryptedCipherText = _rijndaelCryptographyProvider.Decrypt(_importedCipherText, _encryptionKey); + Assert.That(decryptedCipherText, Is.EqualTo(_plainText)); + } } } \ No newline at end of file diff --git a/mRemoteNGTests/Tools/ExternalToolsArgumentParserTests.cs b/mRemoteNGTests/Tools/ExternalToolsArgumentParserTests.cs new file mode 100644 index 000000000..b00735447 --- /dev/null +++ b/mRemoteNGTests/Tools/ExternalToolsArgumentParserTests.cs @@ -0,0 +1,100 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tools; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tools +{ + public class ExternalToolsArgumentParserTests + { + private ExternalToolArgumentParser _argumentParser; + private const string TestString = @"()%!^abc123*<>&|""'\"; + private const string StringAfterMetacharacterEscaping = @"^(^)^%^!^^abc123*^<^>^&^|^""'\"; + private const string StringAfterAllEscaping = @"^(^)^%^!^^abc123*^<^>^&^|\^""'\"; + private const string StringAfterNoEscaping = TestString; + private const int Port = 9933; + private const string PortAsString = "9933"; + private const string SampleCommandString = @"/k echo ()%!^abc123*<>&|""'\"; + + + [OneTimeSetUp] + public void Setup() + { + var connectionInfo = new ConnectionInfo + { + Name = TestString, + Hostname = TestString, + Port = Port, + Username = TestString, + Password = TestString, + Domain = TestString, + Description = TestString, + MacAddress = TestString, + UserField = TestString + }; + _argumentParser = new ExternalToolArgumentParser(connectionInfo); + } + + [OneTimeTearDown] + public void Teardown() + { + _argumentParser = null; + } + + + [TestCase("%NAME%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-NAME%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!NAME%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%HOSTNAME%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-HOSTNAME%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!HOSTNAME%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%PORT%", ExpectedResult = PortAsString)] + [TestCase("%-PORT%", ExpectedResult = PortAsString)] + [TestCase("%!PORT%", ExpectedResult = PortAsString)] + + [TestCase("%USERNAME%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-USERNAME%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!USERNAME%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%PASSWORD%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-PASSWORD%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!PASSWORD%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%DOMAIN%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-DOMAIN%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!DOMAIN%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%DESCRIPTION%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-DESCRIPTION%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!DESCRIPTION%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%MACADDRESS%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-MACADDRESS%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!MACADDRESS%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%USERFIELD%", ExpectedResult = StringAfterAllEscaping)] + [TestCase("%-USERFIELD%", ExpectedResult = StringAfterMetacharacterEscaping)] + [TestCase("%!USERFIELD%", ExpectedResult = StringAfterNoEscaping)] + + [TestCase("%%", ExpectedResult = "%%", TestName = "EmptyVariableTagsNotParsed")] + [TestCase("/k echo %!USERNAME%", ExpectedResult = SampleCommandString, TestName = "ParsingWorksWhenVariableIsNotInFirstPosition")] + [TestCase("%COMSPEC%", ExpectedResult = @"C:\Windows\system32\cmd.exe", TestName = "EnvironmentVariablesParsed")] + [TestCase("%UNSUPPORTEDPARAMETER%", ExpectedResult = "%UNSUPPORTEDPARAMETER%", TestName = "UnsupportedParametersNotParsed")] + [TestCase(@"\%COMSPEC\%", ExpectedResult = @"C:\Windows\system32\cmd.exe", TestName = "BackslashEscapedEnvironmentVariablesParsed")] + [TestCase(@"^%COMSPEC^%", ExpectedResult = "%COMSPEC%", TestName = "ChevronEscapedEnvironmentVariablesNotParsed")] + public string ParserTests(string argumentString) + { + return _argumentParser.ParseArguments(argumentString); + } + + [Test] + public void NullConnectionInfoResultsInEmptyVariables() + { + var parser = new ExternalToolArgumentParser(null); + var parsedText = parser.ParseArguments("test %USERNAME% test"); + Assert.That(parsedText, Is.EqualTo("test test")); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Tree/ConnectionTreeDragAndDropHandlerTests.cs b/mRemoteNGTests/Tree/ConnectionTreeDragAndDropHandlerTests.cs new file mode 100644 index 000000000..1bf478be6 --- /dev/null +++ b/mRemoteNGTests/Tree/ConnectionTreeDragAndDropHandlerTests.cs @@ -0,0 +1,288 @@ +using System.Windows.Forms; +using BrightIdeasSoftware; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Root.PuttySessions; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class ConnectionTreeDragAndDropHandlerTests + { + private ConnectionTreeDragAndDropHandler _dragAndDropHandler; + private RootNodeInfo _rootNode; + private ContainerInfo _container1; + private ContainerInfo _container2; + private ContainerInfo _container3; + private ConnectionInfo _connection1; + private ConnectionInfo _connection2; + private ConnectionInfo _connection3; + private ConnectionInfo _connection4; + private ConnectionInfo _connection5; + + [SetUp] + public void Setup() + { + _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); + InitializeNodes(); + CreateSimpleTreeModel(); + } + + [TearDown] + public void Teardown() + { + _dragAndDropHandler = null; + DestroyNodes(); + } + + [Test] + public void CanDragConnectionOntoContainer() + { + var source = _connection3; + var target = _container1; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.Move)); + } + + [Test] + public void CanDragContainerOntoContainer() + { + var source = _container1; + var target = _container2; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.Move)); + } + + [Test] + public void CanDragContainerBetweenContainers() + { + var source = _container3; + var target = _container2; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.AboveItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.Move)); + } + + [Test] + public void CanDragConnectionBetweenConnections() + { + var source = _connection1; + var target = _connection4; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.AboveItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.Move)); + } + + [Test] + public void CantDragConnectionOntoItself() + { + var source = _connection1; + var target = _connection1; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragContainerOntoItself() + { + var source = _container1; + var target = _container1; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragContainerOntoItsChild() + { + var source = _container2; + var target = _container3; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragContainerBetweenItsChildren() + { + var source = _container3; + var target = _connection4; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.BelowItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragNodeOntoItsCurrentParent() + { + var source = _container3; + var target = _container2; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragRootNodeInfo() + { + var source = _rootNode; + var target = new ContainerInfo(); + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragNodeAboveRootNodeInfo() + { + var source = _connection1; + var target = _rootNode; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.AboveItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragNodeBelowRootNodeInfo() + { + var source = _connection1; + var target = _rootNode; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.BelowItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragPuttySessionInfo() + { + var source = new PuttySessionInfo(); + var target = _container2; + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragConnectionOntoRootPuttySessionNode() + { + var source = _connection1; + var target = new RootPuttySessionsNodeInfo(); + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragContainerOntoRootPuttySessionNode() + { + var source = _container1; + var target = new RootPuttySessionsNodeInfo(); + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.Item); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragNodeAbovePuttySessionNodes() + { + var source = _connection1; + var target = new PuttySessionInfo(); + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.AboveItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void CantDragNodeBelowPuttySessionNodes() + { + var source = _connection1; + var target = new PuttySessionInfo(); + var dragDropEffects = _dragAndDropHandler.CanModelDrop(source, target, DropTargetLocation.BelowItem); + Assert.That(dragDropEffects, Is.EqualTo(DragDropEffects.None)); + } + + [Test] + public void DraggingNodeBelowSiblingRearrangesTheUnderlyingModelCorrectly() + { + var source = _connection3; + var target = _connection5; + var location = DropTargetLocation.BelowItem; + _dragAndDropHandler.DropModel(source, target, location); + var actualIndex = _container3.Children.IndexOf(source); + var expectedIndex = _container3.Children.IndexOf(target) + 1; + Assert.That(actualIndex, Is.EqualTo(expectedIndex)); + } + + [Test] + public void DraggingNodeAboveSiblingRearrangesTheUnderlyingModelCorrectly() + { + var source = _connection3; + var target = _connection5; + var location = DropTargetLocation.AboveItem; + _dragAndDropHandler.DropModel(source, target, location); + var actualIndex = _container3.Children.IndexOf(source); + var expectedIndex = _container3.Children.IndexOf(target) - 1; + Assert.That(actualIndex, Is.EqualTo(expectedIndex)); + } + + [Test] + public void DraggingNodeToNewContainerAddsNodeToTheNewContainer() + { + var source = _connection3; + var target = _container1; + var location = DropTargetLocation.Item; + _dragAndDropHandler.DropModel(source, target, location); + Assert.That(target.Children.Contains(source)); + } + + [Test] + public void DraggingNodeToNewContainerRemovesNodeFromOldContainer() + { + var source = _connection3; + var target = _container1; + var location = DropTargetLocation.Item; + _dragAndDropHandler.DropModel(source, target, location); + Assert.That(!_container3.Children.Contains(source)); + } + + + private void InitializeNodes() + { + _rootNode = new RootNodeInfo(RootNodeType.Connection); + _container1 = new ContainerInfo(); + _container2 = new ContainerInfo(); + _container3 = new ContainerInfo(); + _connection1 = new ConnectionInfo(); + _connection2 = new ConnectionInfo(); + _connection3 = new ConnectionInfo(); + _connection4 = new ConnectionInfo(); + _connection5 = new ConnectionInfo(); + } + + private void CreateSimpleTreeModel() + { + /* + * Root + * |-- container1 + * | L-- connection1 + * L-- container2 + * |-- container3 + * | |-- connection3 + * | |-- connection4 + * | L-- connection5 + * L-- connection2 + */ + _rootNode.AddChild(_container1); + _rootNode.AddChild(_container2); + _container1.AddChild(_connection1); + _container2.AddChild(_container3); + _container2.AddChild(_connection2); + _container3.AddChild(_connection3); + _container3.AddChild(_connection4); + _container3.AddChild(_connection5); + } + + private void DestroyNodes() + { + _rootNode = null; + _container1 = null; + _container2 = null; + _container3 = null; + _connection1 = null; + _connection2 = null; + _connection3 = null; + _connection4 = null; + _connection5 = null; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs b/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs new file mode 100644 index 000000000..b392e962f --- /dev/null +++ b/mRemoteNGTests/Tree/ConnectionTreeModelTests.cs @@ -0,0 +1,40 @@ +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using NUnit.Framework; + + +namespace mRemoteNGTests.Tree +{ + public class ConnectionTreeModelTests + { + private ConnectionTreeModel _connectionTreeModel; + + [SetUp] + public void Setup() + { + _connectionTreeModel = new ConnectionTreeModel(); + } + + [TearDown] + public void Teardown() + { + _connectionTreeModel = null; + } + + [Test] + public void GetChildListProvidesAllChildren() + { + var root = new ContainerInfo(); + var folder1 = new ContainerInfo(); + var folder2 = new ContainerInfo(); + var con1 = new ConnectionInfo(); + root.AddChild(folder1); + folder1.AddChild(folder2); + root.AddChild(con1); + _connectionTreeModel.AddRootNode(root); + var connectionList = _connectionTreeModel.GetRecursiveChildList(root); + Assert.That(connectionList, Is.EquivalentTo(new[] {folder1,folder2,con1})); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index cfc74e278..4ae677eb8 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -73,6 +73,10 @@ nUnitForms\bin\NUnitForms.dll + + ..\packages\ObjectListView.Official.2.9.1\lib\net20\ObjectListView.dll + True + @@ -86,6 +90,7 @@ ..\packages\DockPanelSuite.ThemeVS2012Light.2.10.0\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2012Light.dll True + @@ -102,6 +107,17 @@ + + + + + + + + + + + @@ -110,9 +126,12 @@ - - + + True + True + Resources.resx + @@ -138,10 +157,26 @@ + + ResXFileCodeGenerator + Resources.Designer.cs + TestForm.cs + + + + + + + + + + + + diff --git a/mRemoteNGTests/packages.config b/mRemoteNGTests/packages.config index 135a90b84..8b8b5aff6 100644 --- a/mRemoteNGTests/packages.config +++ b/mRemoteNGTests/packages.config @@ -5,4 +5,5 @@ + \ No newline at end of file diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index 447c724e1..3a85ea824 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -1,6 +1,14 @@ using System; +using System.Linq; using System.Windows.Forms; using mRemoteNG.Config.Connections; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; using mRemoteNG.UI.Forms; @@ -8,43 +16,37 @@ namespace mRemoteNG.App { public static class Export { - public static void ExportToFile(TreeNode rootTreeNode, TreeNode selectedTreeNode) + public static void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel) { try { - Security.Save saveSecurity = new Security.Save(); + var saveSecurity = new Save(); - using (ExportForm exportForm = new ExportForm()) + using (var exportForm = new ExportForm()) { - if (Tree.ConnectionTreeNode.GetNodeType(selectedTreeNode) == Tree.TreeNodeType.Container) + if (selectedNode?.GetTreeNodeType() == TreeNodeType.Container) + exportForm.SelectedFolder = selectedNode as ContainerInfo; + else if (selectedNode?.GetTreeNodeType() == TreeNodeType.Connection) { - exportForm.SelectedFolder = selectedTreeNode; - } - else if (Tree.ConnectionTreeNode.GetNodeType(selectedTreeNode) == Tree.TreeNodeType.Connection) - { - if (Tree.ConnectionTreeNode.GetNodeType(selectedTreeNode.Parent) == Tree.TreeNodeType.Container) - { - exportForm.SelectedFolder = selectedTreeNode.Parent; - } - exportForm.SelectedConnection = selectedTreeNode; + if (selectedNode.Parent.GetTreeNodeType() == TreeNodeType.Container) + exportForm.SelectedFolder = selectedNode.Parent; + exportForm.SelectedConnection = selectedNode; } if (exportForm.ShowDialog(frmMain.Default) != DialogResult.OK) - { return ; - } - TreeNode exportTreeNode; + ConnectionInfo exportTarget; switch (exportForm.Scope) { case ExportForm.ExportScope.SelectedFolder: - exportTreeNode = exportForm.SelectedFolder; + exportTarget = exportForm.SelectedFolder; break; case ExportForm.ExportScope.SelectedConnection: - exportTreeNode = exportForm.SelectedConnection; + exportTarget = exportForm.SelectedConnection; break; default: - exportTreeNode = rootTreeNode; + exportTarget = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); break; } @@ -53,7 +55,7 @@ namespace mRemoteNG.App saveSecurity.Domain = exportForm.IncludeDomain; saveSecurity.Inheritance = exportForm.IncludeInheritance; - SaveExportFile(exportForm.FileName, exportForm.SaveFormat, exportTreeNode, saveSecurity); + SaveExportFile(exportForm.FileName, exportForm.SaveFormat, saveSecurity, exportTarget); } } @@ -63,37 +65,39 @@ namespace mRemoteNG.App } } - private static void SaveExportFile(string fileName, ConnectionsSaver.Format saveFormat, TreeNode rootNode, Security.Save saveSecurity) + private static void SaveExportFile(string fileName, ConnectionsSaver.Format saveFormat, Save saveSecurity, ConnectionInfo exportTarget) { try { - if (Runtime.SQLConnProvider != null) - { - Runtime.SQLConnProvider.Disable(); - } - - ConnectionsSaver connectionsSave = new ConnectionsSaver + ISerializer serializer; + switch (saveFormat) { - Export = true, - ConnectionFileName = fileName, - SaveFormat = saveFormat, - ConnectionList = Runtime.ConnectionList, - ContainerList = Runtime.ContainerList, - RootTreeNode = rootNode, - SaveSecurity = saveSecurity - }; - connectionsSave.SaveConnections(); + case ConnectionsSaver.Format.mRXML: + serializer = new XmlConnectionsSerializer(); + ((XmlConnectionsSerializer) serializer).SaveSecurity = saveSecurity; + break; + case ConnectionsSaver.Format.mRCSV: + serializer = new CsvConnectionsSerializerMremotengFormat(); + ((CsvConnectionsSerializerMremotengFormat)serializer).SaveSecurity = saveSecurity; + break; + case ConnectionsSaver.Format.vRDCSV: + serializer = new CsvConnectionsSerializerRemoteDesktop2008Format(); + ((CsvConnectionsSerializerRemoteDesktop2008Format)serializer).SaveSecurity = saveSecurity; + break; + default: + throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null); + } + var serializedData = serializer.Serialize(exportTarget); + var fileDataProvider = new FileDataProvider(fileName); + fileDataProvider.Save(serializedData); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionStackTrace($"Export.SaveExportFile(\"{fileName}\") failed.", ex); + Runtime.MessageCollector.AddExceptionStackTrace($"Export.SaveExportFile(\"{fileName}\") failed.", ex); } finally { - if (Runtime.SQLConnProvider != null) - { - Runtime.SQLConnProvider.Enable(); - } + Runtime.RemoteConnectionsSyncronizer?.Enable(); } } } diff --git a/mRemoteV1/App/Import.cs b/mRemoteV1/App/Import.cs index 63ff9d705..2638508a2 100644 --- a/mRemoteV1/App/Import.cs +++ b/mRemoteV1/App/Import.cs @@ -1,20 +1,17 @@ using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Windows.Forms; using mRemoteNG.Config.Import; using mRemoteNG.Connection.Protocol; using mRemoteNG.Container; -using mRemoteNG.Tree; -using mRemoteNG.UI.TaskDialog; +using mRemoteNG.Tools; + namespace mRemoteNG.App { public class Import { - #region Private Enumerations - private enum FileType { Unknown = 0, @@ -25,12 +22,8 @@ namespace mRemoteNG.App PuttyConnectionManager } - #endregion - #region Public Methods - - public static void ImportFromFile(TreeNode rootTreeNode, TreeNode selectedTreeNode, - bool alwaysUseSelectedTreeNode = false) + public static void ImportFromFile(ContainerInfo importDestinationContainer, bool alwaysUseSelectedTreeNode = false) { try { @@ -51,37 +44,31 @@ namespace mRemoteNG.App openFileDialog.Filter = string.Join("|", fileTypes.ToArray()); if (openFileDialog.ShowDialog() != DialogResult.OK) - { return; - } - - var parentTreeNode = GetParentTreeNode(rootTreeNode, selectedTreeNode, alwaysUseSelectedTreeNode); - if (parentTreeNode == null) - { - return; - } foreach (var fileName in openFileDialog.FileNames) { try { + IConnectionImporter importer; switch (DetermineFileType(fileName)) { case FileType.mRemoteXml: - Config.Import.mRemoteNGImporter.Import(fileName, parentTreeNode); + importer = new mRemoteNGImporter(); break; case FileType.RemoteDesktopConnection: - RemoteDesktopConnection.Import(fileName, parentTreeNode); + importer = new RemoteDesktopConnectionImporter(); break; case FileType.RemoteDesktopConnectionManager: - RemoteDesktopConnectionManager.Import(fileName, parentTreeNode); + importer = new RemoteDesktopConnectionManagerImporter(); break; case FileType.PuttyConnectionManager: - PuttyConnectionManager.Import(fileName, parentTreeNode); + importer = new PuttyConnectionManagerImporter(); break; default: throw new FileFormatException("Unrecognized file format."); } + importer.Import(fileName, importDestinationContainer); } catch (Exception ex) { @@ -91,14 +78,7 @@ namespace mRemoteNG.App } } - parentTreeNode.Expand(); - var parentContainer = (ContainerInfo) parentTreeNode.Tag; - if (parentContainer != null) - { - parentContainer.IsExpanded = true; - } - - Runtime.SaveConnectionsBG(); + Runtime.SaveConnectionsAsync(); } } catch (Exception ex) @@ -107,60 +87,27 @@ namespace mRemoteNG.App } } - public static void ImportFromActiveDirectory(string ldapPath) + public static void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer) { try { - var rootTreeNode = ConnectionTree.TreeView.Nodes[0]; - var selectedTreeNode = ConnectionTree.TreeView.SelectedNode; - - var parentTreeNode = GetParentTreeNode(rootTreeNode, selectedTreeNode); - if (parentTreeNode == null) - { - return; - } - - ActiveDirectory.Import(ldapPath, parentTreeNode); - - parentTreeNode.Expand(); - var parentContainer = (ContainerInfo) parentTreeNode.Tag; - if (parentContainer != null) - { - parentContainer.IsExpanded = true; - } - - Runtime.SaveConnectionsBG(); + var importer = new ActiveDirectoryImporter(); + importer.Import(ldapPath, importDestinationContainer); + Runtime.SaveConnectionsAsync(); } catch (Exception ex) { - Runtime.MessageCollector.AddExceptionMessage("App.Import.ImportFromActiveDirectory() failed.", ex, - logOnly: true); + Runtime.MessageCollector.AddExceptionMessage("App.Import.ImportFromActiveDirectory() failed.", ex, logOnly: true); } } - public static void ImportFromPortScan(IEnumerable hosts, ProtocolType protocol) + public static void ImportFromPortScan(IEnumerable hosts, ProtocolType protocol, ContainerInfo importDestinationContainer) { try { - var rootTreeNode = ConnectionTree.TreeView.Nodes[0]; - var selectedTreeNode = ConnectionTree.TreeView.SelectedNode; - - var parentTreeNode = GetParentTreeNode(rootTreeNode, selectedTreeNode); - if (parentTreeNode == null) - { - return; - } - - PortScan.Import(hosts, protocol, parentTreeNode); - - parentTreeNode.Expand(); - var parentContainer = (ContainerInfo) parentTreeNode.Tag; - if (parentContainer != null) - { - parentContainer.IsExpanded = true; - } - - Runtime.SaveConnectionsBG(); + var importer = new PortScanImporter(protocol); + importer.Import(hosts, importDestinationContainer); + Runtime.SaveConnectionsAsync(); } catch (Exception ex) { @@ -168,65 +115,8 @@ namespace mRemoteNG.App logOnly: true); } } - #endregion - #region Private Methods - - private static TreeNode GetParentTreeNode(TreeNode rootTreeNode, TreeNode selectedTreeNode, - bool alwaysUseSelectedTreeNode = false) - { - TreeNode parentTreeNode; - - selectedTreeNode = GetContainerTreeNode(selectedTreeNode); - if (selectedTreeNode == null || selectedTreeNode == rootTreeNode) - { - parentTreeNode = rootTreeNode; - } - else - { - if (alwaysUseSelectedTreeNode) - { - parentTreeNode = GetContainerTreeNode(selectedTreeNode); - } - else - { - CTaskDialog.ShowCommandBox(Application.ProductName, Language.strImportLocationMainInstruction, - Language.strImportLocationContent, "", "", "", - string.Format(Language.strImportLocationCommandButtons, Environment.NewLine, rootTreeNode.Text, - selectedTreeNode.Text), true, ESysIcons.Question, 0); - switch (CTaskDialog.CommandButtonResult) - { - case 0: // Root - parentTreeNode = rootTreeNode; - break; - case 1: // Selected Folder - parentTreeNode = GetContainerTreeNode(selectedTreeNode); - break; - default: // Cancel - parentTreeNode = null; - break; - } - } - } - - return parentTreeNode; - } - - private static TreeNode GetContainerTreeNode(TreeNode treeNode) - { - if ((ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Root) || - (ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Container)) - { - return treeNode; - } - if (ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Connection) - { - return treeNode.Parent; - } - return null; - } - private static FileType DetermineFileType(string fileName) { // TODO: Use the file contents to determine the file type instead of trusting the extension @@ -245,7 +135,5 @@ namespace mRemoteNG.App return FileType.Unknown; } } - - #endregion } } \ No newline at end of file diff --git a/mRemoteV1/App/ProgramRoot.cs b/mRemoteV1/App/ProgramRoot.cs index 038e32211..6371359e7 100644 --- a/mRemoteV1/App/ProgramRoot.cs +++ b/mRemoteV1/App/ProgramRoot.cs @@ -24,6 +24,8 @@ namespace mRemoteNG.App private static void StartApplication() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); Startup.Instance.InitializeProgram(); Application.Run(frmMain.Default); } diff --git a/mRemoteV1/App/Runtime.cs b/mRemoteV1/App/Runtime.cs index 9f5443b78..c379c526c 100644 --- a/mRemoteV1/App/Runtime.cs +++ b/mRemoteV1/App/Runtime.cs @@ -2,9 +2,6 @@ using mRemoteNG.App.Info; using mRemoteNG.Config.Connections; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; -using mRemoteNG.Connection.Protocol.RDP; -using mRemoteNG.Container; -using mRemoteNG.Credential; using mRemoteNG.Messages; using mRemoteNG.Tools; using mRemoteNG.Tree; @@ -14,16 +11,17 @@ using System.Collections; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Security; using System.Threading; using System.Windows.Forms; using System.Xml; +using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.UI.Forms; using mRemoteNG.UI.Forms.Input; using mRemoteNG.UI.TaskDialog; using WeifenLuo.WinFormsUI.Docking; using static System.IO.Path; -using TabPage = Crownwood.Magic.Controls.TabPage; namespace mRemoteNG.App @@ -31,50 +29,19 @@ namespace mRemoteNG.App public static class Runtime { #region Public Properties - public static ConnectionList ConnectionList { get; set; } - - private static ConnectionList PreviousConnectionList { get; set; } - - public static ContainerList ContainerList { get; set; } - - private static ContainerList PreviousContainerList { get; set; } - - public static CredentialList CredentialList { get; set; } - - public static CredentialList PreviousCredentialList { get; set; } - public static WindowList WindowList { get; set; } - public static MessageCollector MessageCollector { get; set; } - - public static Tools.Controls.NotificationAreaIcon NotificationAreaIcon { get; set; } - + public static Controls.NotificationAreaIcon NotificationAreaIcon { get; set; } public static bool IsConnectionsFileLoaded { get; set; } - - public static SqlConnectionsProvider SQLConnProvider { get; set; } - - /* - public static System.Timers.Timer TimerSqlWatcher - { - get { return _timerSqlWatcher; } - set - { - _timerSqlWatcher = value; - _timerSqlWatcher.Elapsed += tmrSqlWatcher_Elapsed; - } - } - */ - + public static RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; } public static DateTime LastSqlUpdate { get; set; } - - public static string LastSelected { get; set; } - - public static ConnectionInfo DefaultConnection { get; set; } = DefaultConnectionInfo.Instance; - - public static ConnectionInfoInheritance DefaultInheritance { get; set; } - public static ArrayList ExternalTools { get; set; } = new ArrayList(); - + public static SecureString EncryptionKey { get; set; } = "mR3m".ConvertToSecureString(); + public static ConnectionTreeModel ConnectionTreeModel + { + get { return Windows.TreeForm.ConnectionTreeModel; } + set { Windows.TreeForm.ConnectionTreeModel = value; } + } #endregion #region Panels @@ -229,8 +196,6 @@ namespace mRemoteNG.App { try { - ConnectionList = new ConnectionList(); - ContainerList = new ContainerList(); ConnectionsLoader connectionsLoader = new ConnectionsLoader(); if (filename == GetDefaultStartupConnectionFileName()) @@ -267,15 +232,10 @@ namespace mRemoteNG.App } - connectionsLoader.ConnectionList = ConnectionList; - connectionsLoader.ContainerList = ContainerList; - ConnectionTree.ResetTree(); - connectionsLoader.RootTreeNode = Windows.treeForm.tvConnections.Nodes[0]; - // Load config connectionsLoader.ConnectionFileName = filename; - connectionsLoader.LoadConnections(false); - Windows.treeForm.tvConnections.SelectedNode = connectionsLoader.RootTreeNode; + ConnectionTreeModel = connectionsLoader.LoadConnections(false); + Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel; } catch (Exception ex) { @@ -283,7 +243,7 @@ namespace mRemoteNG.App } } - public static void LoadConnectionsBG() + public static void LoadConnectionsAsync() { _withDialog = false; _loadUpdate = true; @@ -306,22 +266,13 @@ namespace mRemoteNG.App try { // disable sql update checking while we are loading updates - SQLConnProvider?.Disable(); - - if (ConnectionList != null && ContainerList != null) - { - PreviousConnectionList = ConnectionList.Copy(); - PreviousContainerList = ContainerList.Copy(); - } - - ConnectionList = new ConnectionList(); - ContainerList = new ContainerList(); + RemoteConnectionsSyncronizer?.Disable(); if (!Settings.Default.UseSQLServer) { if (withDialog) { - var loadDialog = Tools.Controls.ConnectionsLoadDialog(); + var loadDialog = Controls.ConnectionsLoadDialog(); if (loadDialog.ShowDialog() != DialogResult.OK) return; connectionsLoader.ConnectionFileName = loadDialog.FileName; } @@ -333,31 +284,9 @@ namespace mRemoteNG.App CreateBackupFile(Convert.ToString(connectionsLoader.ConnectionFileName)); } - connectionsLoader.ConnectionList = ConnectionList; - connectionsLoader.ContainerList = ContainerList; - - if (PreviousConnectionList != null && PreviousContainerList != null) - { - connectionsLoader.PreviousConnectionList = PreviousConnectionList; - connectionsLoader.PreviousContainerList = PreviousContainerList; - } - - if (update) - { - connectionsLoader.PreviousSelected = LastSelected; - } - - ConnectionTree.ResetTree(); - - connectionsLoader.RootTreeNode = Windows.treeForm.tvConnections.Nodes[0]; connectionsLoader.UseDatabase = Settings.Default.UseSQLServer; - connectionsLoader.DatabaseHost = Settings.Default.SQLHost; - connectionsLoader.DatabaseName = Settings.Default.SQLDatabaseName; - connectionsLoader.DatabaseUsername = Settings.Default.SQLUser; - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - connectionsLoader.DatabasePassword = cryptographyProvider.Decrypt(Convert.ToString(Settings.Default.SQLPass), GeneralAppInfo.EncryptionKey); - connectionsLoader.DatabaseUpdate = update; - connectionsLoader.LoadConnections(false); + ConnectionTreeModel = connectionsLoader.LoadConnections(false); + Windows.TreeForm.ConnectionTreeModel = ConnectionTreeModel; if (Settings.Default.UseSQLServer) { @@ -377,7 +306,7 @@ namespace mRemoteNG.App } // re-enable sql update checking after updates are loaded - SQLConnProvider?.Enable(); + RemoteConnectionsSyncronizer?.Enable(); } catch (Exception ex) { @@ -416,7 +345,7 @@ namespace mRemoteNG.App { MessageBox.Show(frmMain.Default, string.Format(Language.strErrorStartupConnectionFileLoad, Environment.NewLine, Application.ProductName, GetStartupConnectionFileName(), MiscTools.GetExceptionMessageRecursive(ex)), - "Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error); + @"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } } @@ -432,7 +361,7 @@ namespace mRemoteNG.App try { - string backupFileName = string.Format(Settings.Default.BackupFileNameFormat, fileName, DateTime.UtcNow); + var backupFileName = string.Format(Settings.Default.BackupFileNameFormat, fileName, DateTime.UtcNow); File.Copy(fileName, backupFileName); PruneBackupFiles(fileName); } @@ -495,71 +424,58 @@ namespace mRemoteNG.App } } - public static void SaveConnectionsBG() + public static void SaveConnectionsAsync() { _saveUpdate = true; - Thread t = new Thread(SaveConnectionsBGd); + var t = new Thread(SaveConnectionsBGd); t.SetApartmentState(ApartmentState.STA); t.Start(); } private static bool _saveUpdate; - private static object _saveLock = new object(); + private static readonly object SaveLock = new object(); private static void SaveConnectionsBGd() { - Monitor.Enter(_saveLock); + Monitor.Enter(SaveLock); SaveConnections(_saveUpdate); - Monitor.Exit(_saveLock); + Monitor.Exit(SaveLock); } - public static void SaveConnections(bool Update = false) + public static void SaveConnections(bool update = false) { - if (!IsConnectionsFileLoaded) - { - return; - } + //if (!IsConnectionsFileLoaded) + // return; try { - if (Update && Settings.Default.UseSQLServer == false) - { + if (update && Settings.Default.UseSQLServer == false) return; - } - if (SQLConnProvider != null) - { - SQLConnProvider.Disable(); - } + RemoteConnectionsSyncronizer?.Disable(); - ConnectionsSaver conS = new ConnectionsSaver(); + var connectionsSaver = new ConnectionsSaver(); if (!Settings.Default.UseSQLServer) - { - conS.ConnectionFileName = GetStartupConnectionFileName(); - } + connectionsSaver.ConnectionFileName = GetStartupConnectionFileName(); - conS.ConnectionList = ConnectionList; - conS.ContainerList = ContainerList; - conS.Export = false; - conS.SaveSecurity = new Security.Save(); - conS.RootTreeNode = Windows.treeForm.tvConnections.Nodes[0]; + connectionsSaver.Export = false; + connectionsSaver.SaveSecurity = new Security.Save(); + connectionsSaver.ConnectionTreeModel = ConnectionTreeModel; if (Settings.Default.UseSQLServer) { - conS.SaveFormat = ConnectionsSaver.Format.SQL; - conS.SQLHost = Convert.ToString(Settings.Default.SQLHost); - conS.SQLDatabaseName = Convert.ToString(Settings.Default.SQLDatabaseName); - conS.SQLUsername = Convert.ToString(Settings.Default.SQLUser); + connectionsSaver.SaveFormat = ConnectionsSaver.Format.SQL; + connectionsSaver.SQLHost = Convert.ToString(Settings.Default.SQLHost); + connectionsSaver.SQLDatabaseName = Convert.ToString(Settings.Default.SQLDatabaseName); + connectionsSaver.SQLUsername = Convert.ToString(Settings.Default.SQLUser); var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - conS.SQLPassword = cryptographyProvider.Decrypt(Convert.ToString(Settings.Default.SQLPass), GeneralAppInfo.EncryptionKey); + connectionsSaver.SQLPassword = cryptographyProvider.Decrypt(Convert.ToString(Settings.Default.SQLPass), GeneralAppInfo.EncryptionKey); } - conS.SaveConnections(); + connectionsSaver.SaveConnections(); if (Settings.Default.UseSQLServer) - { LastSqlUpdate = DateTime.Now; - } } catch (Exception ex) { @@ -567,46 +483,39 @@ namespace mRemoteNG.App } finally { - SQLConnProvider?.Enable(); + RemoteConnectionsSyncronizer?.Enable(); } } public static void SaveConnectionsAs() { - ConnectionsSaver connectionsSave = new ConnectionsSaver(); + var connectionsSave = new ConnectionsSaver(); try { - if (SQLConnProvider != null) - { - SQLConnProvider.Disable(); - } + RemoteConnectionsSyncronizer?.Disable(); - using (SaveFileDialog saveFileDialog = new SaveFileDialog()) + using (var saveFileDialog = new SaveFileDialog()) { saveFileDialog.CheckPathExists = true; saveFileDialog.InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath; saveFileDialog.FileName = ConnectionsFileInfo.DefaultConnectionsFile; saveFileDialog.OverwritePrompt = true; - List fileTypes = new List(); + var fileTypes = new List(); fileTypes.AddRange(new[] { Language.strFiltermRemoteXML, "*.xml" }); fileTypes.AddRange(new[] { Language.strFilterAll, "*.*" }); saveFileDialog.Filter = string.Join("|", fileTypes.ToArray()); if (saveFileDialog.ShowDialog(frmMain.Default) != DialogResult.OK) - { return; - } connectionsSave.SaveFormat = ConnectionsSaver.Format.mRXML; connectionsSave.ConnectionFileName = saveFileDialog.FileName; connectionsSave.Export = false; connectionsSave.SaveSecurity = new Security.Save(); - connectionsSave.ConnectionList = ConnectionList; - connectionsSave.ContainerList = ContainerList; - connectionsSave.RootTreeNode = Windows.treeForm.tvConnections.Nodes[0]; + connectionsSave.ConnectionTreeModel = ConnectionTreeModel; connectionsSave.SaveConnections(); @@ -628,7 +537,7 @@ namespace mRemoteNG.App } finally { - SQLConnProvider?.Enable(); + RemoteConnectionsSyncronizer?.Enable(); } } #endregion @@ -669,350 +578,14 @@ namespace mRemoteNG.App return null; } } - - public static void OpenConnection() - { - try - { - OpenConnection(ConnectionInfo.Force.None); - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - public static void OpenConnection(ConnectionInfo.Force Force) - { - try - { - if (Windows.treeForm.tvConnections.SelectedNode.Tag == null) - { - return; - } - - if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession) - { - OpenConnection((ConnectionInfo)Windows.treeForm.tvConnections.SelectedNode.Tag, Force); - } - else if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Container) - { - foreach (TreeNode tNode in ConnectionTree.SelectedNode.Nodes) - { - if (ConnectionTreeNode.GetNodeType(tNode) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession) - { - if (tNode.Tag != null) - { - OpenConnection((ConnectionInfo)tNode.Tag, Force); - } - } - } - } - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - public static void OpenConnection(ConnectionInfo ConnectionInfo) - { - try - { - OpenConnection(ConnectionInfo, ConnectionInfo.Force.None); - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - public static void OpenConnection(ConnectionInfo ConnectionInfo, Form ConnectionForm) - { - try - { - OpenConnectionFinal(ConnectionInfo, ConnectionInfo.Force.None, ConnectionForm); - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - public static void OpenConnection(ConnectionInfo ConnectionInfo, Form ConnectionForm, ConnectionInfo.Force Force) - { - try - { - OpenConnectionFinal(ConnectionInfo, Force, ConnectionForm); - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - public static void OpenConnection(ConnectionInfo ConnectionInfo, ConnectionInfo.Force Force) - { - try - { - OpenConnectionFinal(ConnectionInfo, Force, null); - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - private static void OpenConnectionFinal(ConnectionInfo ConnectionInfo, ConnectionInfo.Force Force, Form ConForm) - { - try - { - if (ConnectionInfo.Hostname == "" && ConnectionInfo.Protocol != ProtocolType.IntApp) - { - MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strConnectionOpenFailedNoHostname); - return; - } - - StartPreConnectionExternalApp(ConnectionInfo); - - if ((Force & ConnectionInfo.Force.DoNotJump) != ConnectionInfo.Force.DoNotJump) - { - if (SwitchToOpenConnection(ConnectionInfo)) - { - return; - } - } - - ProtocolFactory protocolFactory = new ProtocolFactory(); - ProtocolBase newProtocol = protocolFactory.CreateProtocol(ConnectionInfo); - - string connectionPanel = SetConnectionPanel(ConnectionInfo, Force); - Form connectionForm = SetConnectionForm(ConForm, connectionPanel); - Control connectionContainer = SetConnectionContainer(ConnectionInfo, connectionForm); - SetConnectionFormEventHandlers(newProtocol, connectionForm); - SetConnectionEventHandlers(newProtocol); - BuildConnectionInterfaceController(ConnectionInfo, newProtocol, connectionContainer); - - newProtocol.Force = Force; - - if (newProtocol.Initialize() == false) - { - newProtocol.Close(); - return; - } - - if (newProtocol.Connect() == false) - { - newProtocol.Close(); - return; - } - - ConnectionInfo.OpenConnections.Add(newProtocol); - SetTreeNodeImages(ConnectionInfo); - frmMain.Default.SelectedConnection = ConnectionInfo; - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); - } - } - - private static void BuildConnectionInterfaceController(ConnectionInfo ConnectionInfo, ProtocolBase newProtocol, Control connectionContainer) - { - newProtocol.InterfaceControl = new InterfaceControl(connectionContainer, newProtocol, ConnectionInfo); - } - - private static void SetConnectionFormEventHandlers(ProtocolBase newProtocol, Form connectionForm) - { - newProtocol.Closed += ((ConnectionWindow)connectionForm).Prot_Event_Closed; - } - - private static Control SetConnectionContainer(ConnectionInfo ConnectionInfo, Form connectionForm) - { - Control connectionContainer = ((ConnectionWindow)connectionForm).AddConnectionTab(ConnectionInfo); - - if (ConnectionInfo.Protocol == ProtocolType.IntApp) - { - if (GetExtAppByName(ConnectionInfo.ExtApp).Icon != null) - ((TabPage) connectionContainer).Icon = GetExtAppByName(ConnectionInfo.ExtApp).Icon; - } - return connectionContainer; - } - - private static void SetTreeNodeImages(ConnectionInfo ConnectionInfo) - { - if (ConnectionInfo.IsQuickConnect == false) - { - if (ConnectionInfo.Protocol != ProtocolType.IntApp) - { - ConnectionTreeNode.SetNodeImage(ConnectionInfo.TreeNode, TreeImageType.ConnectionOpen); - } - else - { - ExternalTool extApp = GetExtAppByName(ConnectionInfo.ExtApp); - if (extApp != null) - { - if (extApp.TryIntegrate && ConnectionInfo.TreeNode != null) - { - ConnectionTreeNode.SetNodeImage(ConnectionInfo.TreeNode, TreeImageType.ConnectionOpen); - } - } - } - } - } - - private static void SetConnectionEventHandlers(ProtocolBase newProtocol) - { - newProtocol.Disconnected += Prot_Event_Disconnected; - newProtocol.Connected += Prot_Event_Connected; - newProtocol.Closed += Prot_Event_Closed; - newProtocol.ErrorOccured += Prot_Event_ErrorOccured; - } - - private static Form SetConnectionForm(Form ConForm, string connectionPanel) - { - var connectionForm = ConForm ?? WindowList.FromString(connectionPanel); - - if (connectionForm == null) - connectionForm = AddPanel(connectionPanel); - else - ((ConnectionWindow)connectionForm).Show(frmMain.Default.pnlDock); - - connectionForm.Focus(); - return connectionForm; - } - - private static string SetConnectionPanel(ConnectionInfo ConnectionInfo, ConnectionInfo.Force Force) - { - string connectionPanel = ""; - if (ConnectionInfo.Panel == "" || (Force & ConnectionInfo.Force.OverridePanel) == ConnectionInfo.Force.OverridePanel | Settings.Default.AlwaysShowPanelSelectionDlg) - { - frmChoosePanel frmPnl = new frmChoosePanel(); - if (frmPnl.ShowDialog() == DialogResult.OK) - { - connectionPanel = frmPnl.Panel; - } - } - else - { - connectionPanel = ConnectionInfo.Panel; - } - return connectionPanel; - } - - private static void StartPreConnectionExternalApp(ConnectionInfo ConnectionInfo) - { - if (ConnectionInfo.PreExtApp != "") - { - ExternalTool extA = GetExtAppByName(ConnectionInfo.PreExtApp); - extA?.Start(ConnectionInfo); - } - } - - public static bool SwitchToOpenConnection(ConnectionInfo nCi) - { - InterfaceControl IC = FindConnectionContainer(nCi); - if (IC != null) - { - var connectionWindow = (ConnectionWindow)IC.FindForm(); - connectionWindow?.Focus(); - var findForm = (ConnectionWindow)IC.FindForm(); - findForm?.Show(frmMain.Default.pnlDock); - TabPage tabPage = (TabPage)IC.Parent; - tabPage.Selected = true; - return true; - } - return false; - } - #endregion - - #region Event Handlers - - private static void Prot_Event_Disconnected(object sender, string DisconnectedMessage) - { - try - { - MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strProtocolEventDisconnected, DisconnectedMessage), true); - - ProtocolBase Prot = (ProtocolBase)sender; - if (Prot.InterfaceControl.Info.Protocol == ProtocolType.RDP) - { - string ReasonCode = DisconnectedMessage.Split("\r\n".ToCharArray())[0]; - string desc = DisconnectedMessage.Replace("\r\n", " "); - - if (Convert.ToInt32(ReasonCode) > 3) - { - MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strRdpDisconnected + Environment.NewLine + desc); - } - } - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strProtocolEventDisconnectFailed, ex.Message), true); - } - } - - private static void Prot_Event_Closed(object sender) - { - try - { - ProtocolBase Prot = (ProtocolBase)sender; - MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnenctionCloseEvent, true); - MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, Prot.InterfaceControl.Info.Hostname, Prot.InterfaceControl.Info.Protocol.ToString(), Environment.UserName)); - Prot.InterfaceControl.Info.OpenConnections.Remove(Prot); - - if (Prot.InterfaceControl.Info.OpenConnections.Count < 1 && Prot.InterfaceControl.Info.IsQuickConnect == false) - { - ConnectionTreeNode.SetNodeImage(Prot.InterfaceControl.Info.TreeNode, TreeImageType.ConnectionClosed); - } - - if (Prot.InterfaceControl.Info.PostExtApp != "") - { - ExternalTool extA = GetExtAppByName(Prot.InterfaceControl.Info.PostExtApp); - extA?.Start(Prot.InterfaceControl.Info); - } - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnenctionCloseEventFailed + Environment.NewLine + ex.Message, true); - } - } - - private static void Prot_Event_Connected(object sender) - { - ProtocolBase prot = (ProtocolBase)sender; - MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventConnected, true); - MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnectionEventConnectedDetail, prot.InterfaceControl.Info.Hostname, prot.InterfaceControl.Info.Protocol.ToString(), Environment.UserName, prot.InterfaceControl.Info.Description, prot.InterfaceControl.Info.UserField)); - } - - private static void Prot_Event_ErrorOccured(object sender, string ErrorMessage) - { - try - { - MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventErrorOccured, true); - ProtocolBase Prot = (ProtocolBase)sender; - - if (Prot.InterfaceControl.Info.Protocol == ProtocolType.RDP) - { - if (Convert.ToInt32(ErrorMessage) > -1) - { - MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strConnectionRdpErrorDetail, ErrorMessage, ProtocolRDP.FatalErrors.GetError(ErrorMessage))); - } - } - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionEventConnectionFailed + Environment.NewLine + ex.Message, true); - } - } #endregion #region External Apps - public static ExternalTool GetExtAppByName(string Name) + public static ExternalTool GetExtAppByName(string name) { foreach (ExternalTool extA in ExternalTools) { - if (extA.DisplayName == Name) + if (extA.DisplayName == name) return extA; } return null; @@ -1020,129 +593,45 @@ namespace mRemoteNG.App #endregion #region Misc - - private static void GoToURL(string URL) + private static void GoToUrl(string url) { - ConnectionInfo connectionInfo = new ConnectionInfo(); + var connectionInfo = new ConnectionInfo(); connectionInfo.CopyFrom(DefaultConnectionInfo.Instance); connectionInfo.Name = ""; - connectionInfo.Hostname = URL; - if (URL.StartsWith("https:")) - { - connectionInfo.Protocol = ProtocolType.HTTPS; - } - else - { - connectionInfo.Protocol = ProtocolType.HTTP; - } + connectionInfo.Hostname = url; + connectionInfo.Protocol = url.StartsWith("https:") ? ProtocolType.HTTPS : ProtocolType.HTTP; connectionInfo.SetDefaultPort(); connectionInfo.IsQuickConnect = true; - OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); + ConnectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); } public static void GoToWebsite() { - GoToURL(GeneralAppInfo.UrlHome); + GoToUrl(GeneralAppInfo.UrlHome); } public static void GoToDonate() { - GoToURL(GeneralAppInfo.UrlDonate); + GoToUrl(GeneralAppInfo.UrlDonate); } public static void GoToForum() { - GoToURL(GeneralAppInfo.UrlForum); + GoToUrl(GeneralAppInfo.UrlForum); } public static void GoToBugs() { - GoToURL(GeneralAppInfo.UrlBugs); - } - - public static void Report(string Text) - { - try - { - StreamWriter sWr = new StreamWriter(SettingsFileInfo.exePath + "\\Report.log", true); - sWr.WriteLine(Text); - sWr.Close(); - } - catch (Exception) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strLogWriteToFileFailed); - } - } - - public static bool SaveReport() - { - StreamReader streamReader = null; - StreamWriter streamWriter = null; - try - { - streamReader = new StreamReader(SettingsFileInfo.exePath + "\\Report.log"); - string text = streamReader.ReadToEnd(); - streamReader.Close(); - streamWriter = new StreamWriter(GeneralAppInfo.ReportingFilePath, true); - streamWriter.Write(text); - return true; - } - catch (Exception ex) - { - MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strLogWriteToFileFinalLocationFailed + Environment.NewLine + ex.Message, true); - return false; - } - finally - { - if (streamReader != null) - { - streamReader.Close(); - streamReader.Dispose(); - } - if (streamWriter != null) - { - streamWriter.Close(); - streamWriter.Dispose(); - } - } - } - - private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo) - { - if (connectionInfo.OpenConnections.Count > 0) - { - for (int i = 0; i <= WindowList.Count - 1; i++) - { - if (WindowList[i] is ConnectionWindow) - { - ConnectionWindow connectionWindow = (ConnectionWindow)WindowList[i]; - if (connectionWindow.TabController != null) - { - foreach (TabPage t in connectionWindow.TabController.TabPages) - { - if (t.Controls[0] != null && t.Controls[0] is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)t.Controls[0]; - if (IC.Info == connectionInfo) - { - return IC; - } - } - } - } - } - } - } - return null; + GoToUrl(GeneralAppInfo.UrlBugs); } // Override the font of all controls in a container with the default font based on the OS version public static void FontOverride(Control ctlParent) { - foreach (Control tempLoopVar_ctlChild in ctlParent.Controls) + foreach (Control tempLoopVarCtlChild in ctlParent.Controls) { - var ctlChild = tempLoopVar_ctlChild; + var ctlChild = tempLoopVarCtlChild; ctlChild.Font = new Font(SystemFonts.MessageBoxFont.Name, ctlChild.Font.Size, ctlChild.Font.Style, ctlChild.Font.Unit, ctlChild.Font.GdiCharSet); if (ctlChild.Controls.Count > 0) { diff --git a/mRemoteV1/App/Shutdown.cs b/mRemoteV1/App/Shutdown.cs index e93acf242..a3a804051 100644 --- a/mRemoteV1/App/Shutdown.cs +++ b/mRemoteV1/App/Shutdown.cs @@ -1,6 +1,7 @@ using mRemoteNG.Tools; using System; using System.Diagnostics; +using mRemoteNG.Config.Putty; using mRemoteNG.UI.Forms; namespace mRemoteNG.App @@ -36,7 +37,7 @@ namespace mRemoteNG.App private static void StopPuttySessionWatcher() { - Config.Putty.Sessions.StopWatcher(); + PuttySessionsManager.Instance.StopWatcher(); } private static void DisposeNotificationAreaIcon() @@ -47,7 +48,7 @@ namespace mRemoteNG.App private static void SaveConnections() { - if (mRemoteNG.Settings.Default.SaveConsOnExit) + if (Settings.Default.SaveConsOnExit) Runtime.SaveConnections(); } diff --git a/mRemoteV1/App/Startup.cs b/mRemoteV1/App/Startup.cs index d25ca947f..0f2ec796a 100644 --- a/mRemoteV1/App/Startup.cs +++ b/mRemoteV1/App/Startup.cs @@ -52,7 +52,6 @@ namespace mRemoteNG.App DefaultConnectionInheritance.Instance.LoadFrom(Settings.Default, (a)=>"InhDefault"+a); } - public void SetDefaultLayout() { frmMain.Default.pnlDock.Visible = false; @@ -62,11 +61,11 @@ namespace mRemoteNG.App frmMain.Default.pnlDock.DockTopPortion = frmMain.Default.pnlDock.Height * 0.25; frmMain.Default.pnlDock.DockBottomPortion = frmMain.Default.pnlDock.Height * 0.25; - Windows.treePanel.Show(frmMain.Default.pnlDock, DockState.DockLeft); - Windows.configPanel.Show(frmMain.Default.pnlDock); - Windows.configPanel.DockTo(Windows.treePanel.Pane, DockStyle.Bottom, -1); + Windows.TreePanel.Show(frmMain.Default.pnlDock, DockState.DockLeft); + Windows.ConfigPanel.Show(frmMain.Default.pnlDock); + Windows.ConfigPanel.DockTo(Windows.TreePanel.Pane, DockStyle.Bottom, -1); - Windows.screenshotForm.Hide(); + Windows.ScreenshotForm.Hide(); frmMain.Default.pnlDock.Visible = true; } @@ -87,17 +86,14 @@ namespace mRemoteNG.App } } - private void LogStartupData() { - if (Settings.Default.WriteLogFile) - { - LogApplicationData(); - LogCmdLineArgs(); - LogSystemData(); - LogCLRData(); - LogCultureData(); - } + if (!Settings.Default.WriteLogFile) return; + LogApplicationData(); + LogCmdLineArgs(); + LogSystemData(); + LogCLRData(); + LogCultureData(); } private void LogSystemData() @@ -184,13 +180,13 @@ namespace mRemoteNG.App $"System Culture: {Thread.CurrentThread.CurrentUICulture.Name}/{Thread.CurrentThread.CurrentUICulture.NativeName}"); } - public void CreateConnectionsProvider() { - if (Settings.Default.UseSQLServer) - { - SqlConnectionsProvider _sqlConnectionsProvider = new SqlConnectionsProvider(); - } + frmMain.Default.AreWeUsingSqlServerForSavingConnections = Settings.Default.UseSQLServer; + + if (!Settings.Default.UseSQLServer) return; + Runtime.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker()); + Runtime.RemoteConnectionsSyncronizer.Enable(); } private void CheckForUpdate() @@ -246,7 +242,6 @@ namespace mRemoteNG.App } } - private void CheckForAnnouncement() { if (_appUpdate == null) @@ -290,7 +285,6 @@ namespace mRemoteNG.App } } - private void ParseCommandLineArgs() { try diff --git a/mRemoteV1/App/Windows.cs b/mRemoteV1/App/Windows.cs index 6ac63de3f..98934b967 100644 --- a/mRemoteV1/App/Windows.cs +++ b/mRemoteV1/App/Windows.cs @@ -7,58 +7,58 @@ namespace mRemoteNG.App { public static class Windows { - public static ConnectionTreeWindow treeForm; - public static DockContent treePanel = new DockContent(); - public static ConfigWindow configForm; - public static DockContent configPanel = new DockContent(); - public static ErrorAndInfoWindow errorsForm; - public static DockContent errorsPanel = new DockContent(); - public static ScreenshotManagerWindow screenshotForm; - public static DockContent screenshotPanel = new DockContent(); - public static ExportForm exportForm; - public static DockContent exportPanel = new DockContent(); - private static AboutWindow aboutForm; - private static DockContent aboutPanel = new DockContent(); - public static UpdateWindow updateForm; - public static DockContent updatePanel = new DockContent(); - public static SSHTransferWindow sshtransferForm; - private static DockContent sshtransferPanel = new DockContent(); - private static ActiveDirectoryImportWindow adimportForm; - private static DockContent adimportPanel = new DockContent(); - private static HelpWindow helpForm; - private static DockContent helpPanel = new DockContent(); - private static ExternalToolsWindow externalappsForm; - private static DockContent externalappsPanel = new DockContent(); - private static PortScanWindow portscanForm; - private static DockContent portscanPanel = new DockContent(); - private static UltraVNCWindow ultravncscForm; - private static DockContent ultravncscPanel = new DockContent(); - private static ComponentsCheckWindow componentscheckForm; - private static DockContent componentscheckPanel = new DockContent(); - public static AnnouncementWindow AnnouncementForm; - public static DockContent AnnouncementPanel = new DockContent(); + private static AboutWindow _aboutForm; + private static DockContent _aboutPanel = new DockContent(); + private static DockContent _sshtransferPanel = new DockContent(); + private static ActiveDirectoryImportWindow _adimportForm; + private static DockContent _adimportPanel = new DockContent(); + private static HelpWindow _helpForm; + private static DockContent _helpPanel = new DockContent(); + private static ExternalToolsWindow _externalappsForm; + private static DockContent _externalappsPanel = new DockContent(); + private static PortScanWindow _portscanForm; + private static DockContent _portscanPanel = new DockContent(); + private static UltraVNCWindow _ultravncscForm; + private static DockContent _ultravncscPanel = new DockContent(); + private static ComponentsCheckWindow _componentscheckForm; + private static DockContent _componentscheckPanel = new DockContent(); + public static ConnectionTreeWindow TreeForm { get; set; } + public static DockContent TreePanel { get; set; } = new DockContent(); + public static ConfigWindow ConfigForm { get; set; } + public static DockContent ConfigPanel { get; set; } = new DockContent(); + public static ErrorAndInfoWindow ErrorsForm { get; set; } + public static DockContent ErrorsPanel { get; set; } = new DockContent(); + public static ScreenshotManagerWindow ScreenshotForm { get; set; } + public static DockContent ScreenshotPanel { get; set; } = new DockContent(); + public static AnnouncementWindow AnnouncementForm { get; set; } + public static DockContent AnnouncementPanel { get; set; } = new DockContent(); + public static UpdateWindow UpdateForm { get; set; } + public static DockContent UpdatePanel { get; set; } = new DockContent(); + public static SSHTransferWindow SshtransferForm { get; set; } + + public static void Show(WindowType windowType) { try { if (windowType.Equals(WindowType.About)) { - if (aboutForm == null || aboutForm.IsDisposed) + if (_aboutForm == null || _aboutForm.IsDisposed) { - aboutForm = new AboutWindow(aboutPanel); - aboutPanel = aboutForm; + _aboutForm = new AboutWindow(_aboutPanel); + _aboutPanel = _aboutForm; } - aboutForm.Show(frmMain.Default.pnlDock); + _aboutForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.ActiveDirectoryImport)) { - if (adimportForm == null || adimportForm.IsDisposed) + if (_adimportForm == null || _adimportForm.IsDisposed) { - adimportForm = new ActiveDirectoryImportWindow(adimportPanel); - adimportPanel = adimportForm; + _adimportForm = new ActiveDirectoryImportWindow(_adimportPanel); + _adimportPanel = _adimportForm; } - adimportPanel.Show(frmMain.Default.pnlDock); + _adimportPanel.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.Options)) { @@ -69,60 +69,60 @@ namespace mRemoteNG.App } else if (windowType.Equals(WindowType.SSHTransfer)) { - sshtransferForm = new SSHTransferWindow(sshtransferPanel); - sshtransferPanel = sshtransferForm; - sshtransferForm.Show(frmMain.Default.pnlDock); + SshtransferForm = new SSHTransferWindow(_sshtransferPanel); + _sshtransferPanel = SshtransferForm; + SshtransferForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.Update)) { - if (updateForm == null || updateForm.IsDisposed) + if (UpdateForm == null || UpdateForm.IsDisposed) { - updateForm = new UpdateWindow(updatePanel); - updatePanel = updateForm; + UpdateForm = new UpdateWindow(UpdatePanel); + UpdatePanel = UpdateForm; } - updateForm.Show(frmMain.Default.pnlDock); + UpdateForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.Help)) { - if (helpForm == null || helpForm.IsDisposed) + if (_helpForm == null || _helpForm.IsDisposed) { - helpForm = new HelpWindow(helpPanel); - helpPanel = helpForm; + _helpForm = new HelpWindow(_helpPanel); + _helpPanel = _helpForm; } - helpForm.Show(frmMain.Default.pnlDock); + _helpForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.ExternalApps)) { - if (externalappsForm == null || externalappsForm.IsDisposed) + if (_externalappsForm == null || _externalappsForm.IsDisposed) { - externalappsForm = new ExternalToolsWindow(externalappsPanel); - externalappsPanel = externalappsForm; + _externalappsForm = new ExternalToolsWindow(_externalappsPanel); + _externalappsPanel = _externalappsForm; } - externalappsForm.Show(frmMain.Default.pnlDock); + _externalappsForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.PortScan)) { - portscanForm = new PortScanWindow(portscanPanel); - portscanPanel = portscanForm; - portscanForm.Show(frmMain.Default.pnlDock); + _portscanForm = new PortScanWindow(_portscanPanel); + _portscanPanel = _portscanForm; + _portscanForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.UltraVNCSC)) { - if (ultravncscForm == null || ultravncscForm.IsDisposed) + if (_ultravncscForm == null || _ultravncscForm.IsDisposed) { - ultravncscForm = new UltraVNCWindow(ultravncscPanel); - ultravncscPanel = ultravncscForm; + _ultravncscForm = new UltraVNCWindow(_ultravncscPanel); + _ultravncscPanel = _ultravncscForm; } - ultravncscForm.Show(frmMain.Default.pnlDock); + _ultravncscForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.ComponentsCheck)) { - if (componentscheckForm == null || componentscheckForm.IsDisposed) + if (_componentscheckForm == null || _componentscheckForm.IsDisposed) { - componentscheckForm = new ComponentsCheckWindow(componentscheckPanel); - componentscheckPanel = componentscheckForm; + _componentscheckForm = new ComponentsCheckWindow(_componentscheckPanel); + _componentscheckPanel = _componentscheckForm; } - componentscheckForm.Show(frmMain.Default.pnlDock); + _componentscheckForm.Show(frmMain.Default.pnlDock); } else if (windowType.Equals(WindowType.Announcement)) { diff --git a/mRemoteV1/Config/Connections/ConnectionsDecryptor.cs b/mRemoteV1/Config/Connections/ConnectionsDecryptor.cs new file mode 100644 index 000000000..5419b0317 --- /dev/null +++ b/mRemoteV1/Config/Connections/ConnectionsDecryptor.cs @@ -0,0 +1,96 @@ +using System; +using System.Security; +using mRemoteNG.App; +using mRemoteNG.Security; +using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.Config.Connections +{ + public class ConnectionsDecryptor + { + private readonly ICryptographyProvider _cryptographyProvider; + + public ConnectionsDecryptor() + { + _cryptographyProvider = new LegacyRijndaelCryptographyProvider(); + } + + public string DecryptConnections(string xml) + { + var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); + + if (string.IsNullOrEmpty(xml)) return ""; + if (xml.Contains("")) return xml; + + var strDecr = ""; + bool notDecr; + + try + { + strDecr = cryptographyProvider.Decrypt(xml, Runtime.EncryptionKey); + notDecr = strDecr == xml; + } + catch (Exception) + { + notDecr = true; + } + + if (notDecr) + { + if (Authenticate(xml, true)) + { + strDecr = cryptographyProvider.Decrypt(xml, Runtime.EncryptionKey); + notDecr = false; + } + + if (notDecr == false) + return strDecr; + } + else + { + return strDecr; + } + + return ""; + } + + public bool ConnectionsFileIsAuthentic(string protectedString, RootNodeInfo rootInfo) + { + var connectionsFileIsNotEncrypted = _cryptographyProvider.Decrypt(protectedString, Runtime.EncryptionKey) == "ThisIsNotProtected"; + return connectionsFileIsNotEncrypted || Authenticate(protectedString, false, rootInfo); + } + + private bool Authenticate(string value, bool compareToOriginalValue, RootNodeInfo rootInfo = null) + { + var passwordName = ""; + //passwordName = Path.GetFileName(ConnectionFileName); + + if (compareToOriginalValue) + { + while (_cryptographyProvider.Decrypt(value, Runtime.EncryptionKey) == value) + { + Runtime.EncryptionKey = Tools.MiscTools.PasswordDialog(passwordName, false); + if (Runtime.EncryptionKey.Length == 0) + return false; + } + } + else + { + while (_cryptographyProvider.Decrypt(value, Runtime.EncryptionKey) != "ThisIsProtected") + { + Runtime.EncryptionKey = Tools.MiscTools.PasswordDialog(passwordName, false); + if (Runtime.EncryptionKey.Length == 0) + return false; + } + + if (rootInfo == null) return true; + rootInfo.Password = true; + rootInfo.PasswordString = Runtime.EncryptionKey.ConvertToUnsecureString(); + } + + return true; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/ConnectionsLoader.cs b/mRemoteV1/Config/Connections/ConnectionsLoader.cs index cb3953c51..f0009f5d8 100644 --- a/mRemoteV1/Config/Connections/ConnectionsLoader.cs +++ b/mRemoteV1/Config/Connections/ConnectionsLoader.cs @@ -1,6 +1,8 @@ -using System.Windows.Forms; -using mRemoteNG.Connection; -using mRemoteNG.Container; +using mRemoteNG.Config.DatabaseConnectors; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Putty; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Tree; using mRemoteNG.UI.Forms; @@ -9,57 +11,38 @@ namespace mRemoteNG.Config.Connections public class ConnectionsLoader { public bool UseDatabase { get; set; } - public string DatabaseHost { get; set; } - public string DatabaseName { get; set; } - public string DatabaseUsername { get; set; } - public string DatabasePassword { get; set; } - public bool DatabaseUpdate { get; set; } - public string PreviousSelected { get; set; } public string ConnectionFileName { get; set; } - public TreeNode RootTreeNode { get; set; } - public ConnectionList ConnectionList { get; set; } - public ContainerList ContainerList { get; set; } - public ConnectionList PreviousConnectionList { get; set; } - public ContainerList PreviousContainerList { get; set; } - public void LoadConnections(bool import) + public ConnectionTreeModel LoadConnections(bool import) { + IDeserializer deserializer; if (UseDatabase) { - var sqlConnectionsLoader = new SqlConnectionsLoader() - { - ConnectionList = ConnectionList, - ContainerList = ContainerList, - PreviousConnectionList = PreviousConnectionList, - PreviousContainerList = PreviousContainerList, - PreviousSelected = PreviousSelected, - RootTreeNode = RootTreeNode, - DatabaseName = DatabaseName, - DatabaseHost = DatabaseHost, - DatabasePassword = DatabasePassword, - DatabaseUpdate = DatabaseUpdate, - DatabaseUsername = DatabaseUsername - }; - sqlConnectionsLoader.LoadFromSql(); + var connector = new SqlDatabaseConnector(); + var dataProvider = new SqlDataProvider(connector); + var dataTable = dataProvider.Load(); + deserializer = new DataTableDeserializer(dataTable); } else { - var xmlConnectionsLoader = new XmlConnectionsLoader() - { - ConnectionFileName = ConnectionFileName, - ConnectionList = ConnectionList, - ContainerList = ContainerList, - RootTreeNode = RootTreeNode, - }; - xmlConnectionsLoader.LoadFromXml(import); + var dataProvider = new FileDataProvider(ConnectionFileName); + var xmlString = dataProvider.Load(); + deserializer = new XmlConnectionsDeserializer(xmlString); } - - frmMain.Default.AreWeUsingSqlServerForSavingConnections = UseDatabase; - frmMain.Default.ConnectionsFileName = ConnectionFileName; - - if (!import) - Putty.Sessions.AddSessionsToTree(); + + var connectionTreeModel = deserializer.Deserialize(); + + if (connectionTreeModel != null) + frmMain.Default.ConnectionsFileName = ConnectionFileName; + else + connectionTreeModel = new ConnectionTreeModel(); + + if (import) return connectionTreeModel; + PuttySessionsManager.Instance.AddSessions(); + connectionTreeModel.RootNodes.AddRange(PuttySessionsManager.Instance.RootPuttySessionsNodes); + + return connectionTreeModel; } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/ConnectionsSaver.cs b/mRemoteV1/Config/Connections/ConnectionsSaver.cs index 416de697e..1fb14e0f9 100644 --- a/mRemoteV1/Config/Connections/ConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/ConnectionsSaver.cs @@ -3,12 +3,16 @@ using System.Data.SqlClient; using System.Drawing; using System.Globalization; using System.IO; +using System.Linq; using System.Security; using System.Text; using System.Windows.Forms; using System.Xml; using mRemoteNG.App; using mRemoteNG.App.Info; +using mRemoteNG.Config.DatabaseConnectors; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol.RDP; @@ -40,10 +44,7 @@ namespace mRemoteNG.Config.Connections #region Private Properties private XmlTextWriter _xmlTextWriter; private SecureString _password = GeneralAppInfo.EncryptionKey; - - private SqlConnection _sqlConnection; - private SqlCommand _sqlQuery; - + private int _currentNodeIndex; private string _parentConstantId = Convert.ToString(0); #endregion @@ -59,8 +60,7 @@ namespace mRemoteNG.Config.Connections public bool Export {get; set;} public Format SaveFormat {get; set;} public Save SaveSecurity {get; set;} - public ConnectionList ConnectionList {get; set;} - public ContainerList ContainerList {get; set;} + public ConnectionTreeModel ConnectionTreeModel { get; set; } #endregion #region Public Methods @@ -69,27 +69,23 @@ namespace mRemoteNG.Config.Connections switch (SaveFormat) { case Format.SQL: - SaveToSQL(); + SaveToSql(); break; case Format.mRCSV: - SaveTomRCSV(); - break; + SaveToMremotengFormattedCsv(); + break; case Format.vRDvRE: SaveToVRE(); break; case Format.vRDCSV: - SaveTovRDCSV(); + SaveToRemoteDesktop2008FormattedCsv(); break; default: SaveToXml(); if (mRemoteNG.Settings.Default.EncryptCompleteConnectionsFile) - { EncryptCompleteFile(); - } if (!Export) - { frmMain.Default.ConnectionsFileName = ConnectionFileName; - } break; } frmMain.Default.AreWeUsingSqlServerForSavingConnections = SaveFormat == Format.SQL; @@ -97,1016 +93,203 @@ namespace mRemoteNG.Config.Connections #endregion #region SQL - private bool VerifyDatabaseVersion(SqlConnection sqlConnection) + private void SaveToSql() { - bool isVerified = false; - SqlDataReader sqlDataReader = null; - try - { - SqlCommand sqlCommand = new SqlCommand("SELECT * FROM tblRoot", sqlConnection); - sqlDataReader = sqlCommand.ExecuteReader(); - if (!sqlDataReader.HasRows) - { - return true; // assume new empty database - } - sqlDataReader.Read(); - - var databaseVersion = new Version(Convert.ToString(sqlDataReader["confVersion"], CultureInfo.InvariantCulture)); - - sqlDataReader.Close(); - - if (databaseVersion.CompareTo(new Version(2, 2)) == 0) // 2.2 - { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format("Upgrading database from version {0} to version {1}.", databaseVersion, "2.3")); - sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD EnableFontSmoothing bit NOT NULL DEFAULT 0, EnableDesktopComposition bit NOT NULL DEFAULT 0, InheritEnableFontSmoothing bit NOT NULL DEFAULT 0, InheritEnableDesktopComposition bit NOT NULL DEFAULT 0;", sqlConnection); - sqlCommand.ExecuteNonQuery(); - databaseVersion = new Version(2, 3); - } - - if (databaseVersion.CompareTo(new Version(2, 3)) == 0) // 2.3 - { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format("Upgrading database from version {0} to version {1}.", databaseVersion, "2.4")); - sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD UseCredSsp bit NOT NULL DEFAULT 1, InheritUseCredSsp bit NOT NULL DEFAULT 0;", sqlConnection); - sqlCommand.ExecuteNonQuery(); - databaseVersion = new Version(2, 4); - } - - if (databaseVersion.CompareTo(new Version(2, 4)) == 0) // 2.4 - { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format("Upgrading database from version {0} to version {1}.", databaseVersion, "2.5")); - sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD LoadBalanceInfo varchar (1024) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, AutomaticResize bit NOT NULL DEFAULT 1, InheritLoadBalanceInfo bit NOT NULL DEFAULT 0, InheritAutomaticResize bit NOT NULL DEFAULT 0;", sqlConnection); - sqlCommand.ExecuteNonQuery(); - databaseVersion = new Version(2, 5); - } - - if (databaseVersion.CompareTo(new Version(2, 5)) == 0) // 2.5 - { - isVerified = true; - } - - if (isVerified == false) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strErrorBadDatabaseVersion, databaseVersion, GeneralAppInfo.ProdName)); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strErrorVerifyDatabaseVersionFailed, ex.Message)); - } - finally - { - if (sqlDataReader != null) - { - if (!sqlDataReader.IsClosed) - { - sqlDataReader.Close(); - } - } - } - return isVerified; - } - - private void SaveToSQL() - { - if (SQLUsername != "") - { - _sqlConnection = new SqlConnection("Data Source=" + SQLHost + ";Initial Catalog=" + SQLDatabaseName + ";User Id=" + SQLUsername + ";Password=" + SQLPassword); - } - else - { - _sqlConnection = new SqlConnection("Data Source=" + SQLHost + ";Initial Catalog=" + SQLDatabaseName + ";Integrated Security=True"); - } - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); + var sqlConnector = new SqlDatabaseConnector(); + sqlConnector.Connect(); - _sqlConnection.Open(); - - if (!VerifyDatabaseVersion(_sqlConnection)) + if (!VerifyDatabaseVersion(sqlConnector)) { Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed); return ; } - var tN = (TreeNode)RootTreeNode.Clone(); - - string strProtected; - if (tN.Tag != null) - { - if (((RootNodeInfo) tN.Tag).Password) - { - _password = Convert.ToString(((RootNodeInfo) tN.Tag).PasswordString).ConvertToSecureString(); - strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password); - } - else - { - strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password); - } - } - else - { - strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password); - } - - _sqlQuery = new SqlCommand("DELETE FROM tblRoot", _sqlConnection); - _sqlQuery.ExecuteNonQuery(); + var rootTreeNode = Runtime.ConnectionTreeModel.RootNodes.OfType().First(); - _sqlQuery = new SqlCommand("INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(\'" + MiscTools.PrepareValueForDB(tN.Text) + "\', 0, \'" + strProtected + "\'," + ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture) + ")", _sqlConnection); - _sqlQuery.ExecuteNonQuery(); - - _sqlQuery = new SqlCommand("DELETE FROM tblCons", _sqlConnection); - _sqlQuery.ExecuteNonQuery(); - - TreeNodeCollection tNC = tN.Nodes; + UpdateRootNodeTable(rootTreeNode, sqlConnector); + UpdateConnectionsTable(rootTreeNode, sqlConnector); + UpdateUpdatesTable(sqlConnector); - SaveNodesSQL(tNC); - - _sqlQuery = new SqlCommand("DELETE FROM tblUpdate", _sqlConnection); - _sqlQuery.ExecuteNonQuery(); - _sqlQuery = new SqlCommand("INSERT INTO tblUpdate (LastUpdate) VALUES(\'" + MiscTools.DBDate(DateTime.Now) + "\')", _sqlConnection); - _sqlQuery.ExecuteNonQuery(); - - _sqlConnection.Close(); + sqlConnector.Disconnect(); + sqlConnector.Dispose(); } - - private void SaveNodesSQL(TreeNodeCollection tnc) - { - foreach (TreeNode node in tnc) - { - _currentNodeIndex++; - - ConnectionInfo curConI; - _sqlQuery = new SqlCommand("INSERT INTO tblCons (Name, Type, Expanded, Description, Icon, Panel, Username, " + "DomainName, Password, Hostname, Protocol, PuttySession, " + "Port, ConnectToConsole, RenderingEngine, ICAEncryptionStrength, RDPAuthenticationLevel, LoadBalanceInfo, Colors, Resolution, AutomaticResize, DisplayWallpaper, " + "DisplayThemes, EnableFontSmoothing, EnableDesktopComposition, CacheBitmaps, RedirectDiskDrives, RedirectPorts, " + "RedirectPrinters, RedirectSmartCards, RedirectSound, RedirectKeys, " + "Connected, PreExtApp, PostExtApp, MacAddress, UserField, ExtApp, VNCCompression, VNCEncoding, VNCAuthMode, " + "VNCProxyType, VNCProxyIP, VNCProxyPort, VNCProxyUsername, VNCProxyPassword, " + "VNCColors, VNCSmartSizeMode, VNCViewOnly, " + "RDGatewayUsageMethod, RDGatewayHostname, RDGatewayUseConnectionCredentials, RDGatewayUsername, RDGatewayPassword, RDGatewayDomain, " + "UseCredSsp, " + "InheritCacheBitmaps, InheritColors, " + "InheritDescription, InheritDisplayThemes, InheritDisplayWallpaper, InheritEnableFontSmoothing, InheritEnableDesktopComposition, InheritDomain, " + "InheritIcon, InheritPanel, InheritPassword, InheritPort, " + "InheritProtocol, InheritPuttySession, InheritRedirectDiskDrives, " + "InheritRedirectKeys, InheritRedirectPorts, InheritRedirectPrinters, " + "InheritRedirectSmartCards, InheritRedirectSound, InheritResolution, InheritAutomaticResize, " + "InheritUseConsoleSession, InheritRenderingEngine, InheritUsername, InheritICAEncryptionStrength, InheritRDPAuthenticationLevel, InheritLoadBalanceInfo, " + "InheritPreExtApp, InheritPostExtApp, InheritMacAddress, InheritUserField, InheritExtApp, InheritVNCCompression, InheritVNCEncoding, " + "InheritVNCAuthMode, InheritVNCProxyType, InheritVNCProxyIP, InheritVNCProxyPort, " + "InheritVNCProxyUsername, InheritVNCProxyPassword, InheritVNCColors, " + "InheritVNCSmartSizeMode, InheritVNCViewOnly, " + "InheritRDGatewayUsageMethod, InheritRDGatewayHostname, InheritRDGatewayUseConnectionCredentials, InheritRDGatewayUsername, InheritRDGatewayPassword, InheritRDGatewayDomain, " - + "InheritUseCredSsp, " + "PositionID, ParentID, ConstantID, LastChange)" + "VALUES (", _sqlConnection - ); - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) - { - //_xmlTextWriter.WriteStartElement("Node") - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(node.Text) + "\',"; //Name - _sqlQuery.CommandText += "\'" + ConnectionTreeNode.GetNodeType(node) + "\',"; //Type - } - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) //container - { - _sqlQuery.CommandText += "\'" + ContainerList[node.Tag].IsExpanded + "\',"; //Expanded - curConI = ContainerList[node.Tag]; - SaveConnectionFieldsSQL(curConI); - - _sqlQuery.CommandText = MiscTools.PrepareForDB(_sqlQuery.CommandText); - _sqlQuery.ExecuteNonQuery(); - //_parentConstantId = _currentNodeIndex - SaveNodesSQL(node.Nodes); - //_xmlTextWriter.WriteEndElement() - } - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection) - { - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - curConI = ConnectionList[node.Tag]; - SaveConnectionFieldsSQL(curConI); - //_xmlTextWriter.WriteEndElement() - _sqlQuery.CommandText = MiscTools.PrepareForDB(_sqlQuery.CommandText); - _sqlQuery.ExecuteNonQuery(); - } - - //_parentConstantId = 0 - } - } - - private void SaveConnectionFieldsSQL(ConnectionInfo curConI) - { + + private bool VerifyDatabaseVersion(SqlDatabaseConnector sqlDatabaseConnector) + { + var isVerified = false; + try + { + var databaseVersion = GetDatabaseVersion(sqlDatabaseConnector); + SqlCommand sqlCommand; + + if (databaseVersion.Equals(new Version())) + { + return true; + } + + if (databaseVersion.CompareTo(new Version(2, 2)) == 0) // 2.2 + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.3."); + sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD EnableFontSmoothing bit NOT NULL DEFAULT 0, EnableDesktopComposition bit NOT NULL DEFAULT 0, InheritEnableFontSmoothing bit NOT NULL DEFAULT 0, InheritEnableDesktopComposition bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection); + sqlCommand.ExecuteNonQuery(); + databaseVersion = new Version(2, 3); + } + + if (databaseVersion.CompareTo(new Version(2, 3)) == 0) // 2.3 + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.4."); + sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD UseCredSsp bit NOT NULL DEFAULT 1, InheritUseCredSsp bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection); + sqlCommand.ExecuteNonQuery(); + databaseVersion = new Version(2, 4); + } + + if (databaseVersion.CompareTo(new Version(2, 4)) == 0) // 2.4 + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"Upgrading database from version {databaseVersion} to version 2.5."); + sqlCommand = new SqlCommand("ALTER TABLE tblCons ADD LoadBalanceInfo varchar (1024) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, AutomaticResize bit NOT NULL DEFAULT 1, InheritLoadBalanceInfo bit NOT NULL DEFAULT 0, InheritAutomaticResize bit NOT NULL DEFAULT 0;", sqlDatabaseConnector.SqlConnection); + sqlCommand.ExecuteNonQuery(); + databaseVersion = new Version(2, 5); + } + + if (databaseVersion.CompareTo(new Version(2, 5)) == 0) // 2.5 + isVerified = true; + + if (isVerified == false) + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strErrorBadDatabaseVersion, databaseVersion, GeneralAppInfo.ProdName)); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strErrorVerifyDatabaseVersionFailed, ex.Message)); + } + return isVerified; + } + + private Version GetDatabaseVersion(SqlDatabaseConnector sqlDatabaseConnector) + { + Version databaseVersion; + SqlDataReader sqlDataReader = null; + try + { + var sqlCommand = new SqlCommand("SELECT * FROM tblRoot", sqlDatabaseConnector.SqlConnection); + sqlDataReader = sqlCommand.ExecuteReader(); + if (!sqlDataReader.HasRows) + return new Version(); // assume new empty database + else + sqlDataReader.Read(); + databaseVersion = new Version(Convert.ToString(sqlDataReader["confVersion"], CultureInfo.InvariantCulture)); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, $"Retrieving database version failed. {ex}"); + throw; + } + finally + { + if (sqlDataReader != null && !sqlDataReader.IsClosed) + sqlDataReader.Close(); + } + return databaseVersion; + } + + private void UpdateRootNodeTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector) + { var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - ConnectionInfo with_1 = curConI; - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Description) + "\',"; - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Icon) + "\',"; - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Panel) + "\',"; - - if (SaveSecurity.Username) - { - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Username) + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } - - if (SaveSecurity.Domain) - { - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Domain) + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } - - if (SaveSecurity.Password) - { - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(cryptographyProvider.Encrypt(with_1.Password, _password)) + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } + string strProtected; + if (rootTreeNode != null) + { + if (rootTreeNode.Password) + { + _password = Convert.ToString(rootTreeNode.PasswordString).ConvertToSecureString(); + strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password); + } + else + { + strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password); + } + } + else + { + strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password); + } - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.Hostname) + "\',"; - _sqlQuery.CommandText += "\'" + with_1.Protocol + "\',"; - _sqlQuery.CommandText += "\'" + MiscTools.PrepareValueForDB(with_1.PuttySession) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Port) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.UseConsoleSession) + "\',"; - _sqlQuery.CommandText += "\'" + with_1.RenderingEngine + "\',"; - _sqlQuery.CommandText += "\'" + with_1.ICAEncryptionStrength + "\',"; - _sqlQuery.CommandText += "\'" + with_1.RDPAuthenticationLevel + "\',"; - _sqlQuery.CommandText += "\'" + with_1.LoadBalanceInfo + "\',"; - _sqlQuery.CommandText += "\'" + with_1.Colors + "\',"; - _sqlQuery.CommandText += "\'" + with_1.Resolution + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.AutomaticResize) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.DisplayWallpaper) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.DisplayThemes) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.EnableFontSmoothing) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.EnableDesktopComposition) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.CacheBitmaps) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.RedirectDiskDrives) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.RedirectPorts) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.RedirectPrinters) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.RedirectSmartCards) + "\',"; - _sqlQuery.CommandText += "\'" + with_1.RedirectSound + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.RedirectKeys) + "\',"; - - if (curConI.OpenConnections.Count > 0) - { - _sqlQuery.CommandText += 1 + ","; - } - else - { - _sqlQuery.CommandText += 0 + ","; - } - - _sqlQuery.CommandText += "\'" + with_1.PreExtApp + "\',"; - _sqlQuery.CommandText += "\'" + with_1.PostExtApp + "\',"; - _sqlQuery.CommandText += "\'" + with_1.MacAddress + "\',"; - _sqlQuery.CommandText += "\'" + with_1.UserField + "\',"; - _sqlQuery.CommandText += "\'" + with_1.ExtApp + "\',"; - - _sqlQuery.CommandText += "\'" + with_1.VNCCompression + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCEncoding + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCAuthMode + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCProxyType + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCProxyIP + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.VNCProxyPort) + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCProxyUsername + "\',"; - _sqlQuery.CommandText += "\'" + cryptographyProvider.Encrypt(with_1.VNCProxyPassword, _password) + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCColors + "\',"; - _sqlQuery.CommandText += "\'" + with_1.VNCSmartSizeMode + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.VNCViewOnly) + "\',"; - - _sqlQuery.CommandText += "\'" + with_1.RDGatewayUsageMethod + "\',"; - _sqlQuery.CommandText += "\'" + with_1.RDGatewayHostname + "\',"; - _sqlQuery.CommandText += "\'" + with_1.RDGatewayUseConnectionCredentials + "\',"; - - if (SaveSecurity.Username) - { - _sqlQuery.CommandText += "\'" + with_1.RDGatewayUsername + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } - - if (SaveSecurity.Password) - { - _sqlQuery.CommandText += "\'" + cryptographyProvider.Encrypt(with_1.RDGatewayPassword, _password) + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } - - if (SaveSecurity.Domain) - { - _sqlQuery.CommandText += "\'" + with_1.RDGatewayDomain + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + "" + "\',"; - } - - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.UseCredSsp) + "\',"; - - if (SaveSecurity.Inheritance) - { - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.CacheBitmaps) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Colors) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Description) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.DisplayThemes) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.DisplayWallpaper) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.EnableFontSmoothing) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.EnableDesktopComposition) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Domain) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Icon) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Panel) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Password) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Port) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Protocol) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.PuttySession) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectDiskDrives) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectKeys) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectPorts) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectPrinters) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectSmartCards) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RedirectSound) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Resolution) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.AutomaticResize) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.UseConsoleSession) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RenderingEngine) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.Username) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.ICAEncryptionStrength) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDPAuthenticationLevel) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.LoadBalanceInfo) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.PreExtApp) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.PostExtApp) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.MacAddress) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.UserField) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.ExtApp) + "\',"; - - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCCompression) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCEncoding) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCAuthMode) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCProxyType) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCProxyIP) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCProxyPort) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCProxyUsername) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCProxyPassword) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCColors) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCSmartSizeMode) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.VNCViewOnly) + "\',"; - - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayUsageMethod) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayHostname) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayUseConnectionCredentials) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayUsername) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayPassword) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.RDGatewayDomain) + "\',"; - - _sqlQuery.CommandText += "\'" + Convert.ToString(with_1.Inheritance.UseCredSsp) + "\',"; - } - else - { - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .AutomaticResize - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .LoadBalanceInfo - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; - - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayUsageMethod - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayHostname - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayUseConnectionCredentials - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayUsername - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayPassword - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .RDGatewayDomain - - _sqlQuery.CommandText += "\'" + Convert.ToString(false) + "\',"; // .UseCredSsp - } - - with_1.PositionID = _currentNodeIndex; - - if (with_1.IsContainer == false) - { - if (with_1.Parent != null) - { - _parentConstantId = Convert.ToString(with_1.Parent.ConstantID); - } - else - { - _parentConstantId = Convert.ToString(0); - } - } - else - { - if (with_1.Parent.Parent != null) - { - _parentConstantId = Convert.ToString(with_1.Parent.Parent.ConstantID); - } - else - { - _parentConstantId = Convert.ToString(0); - } - } - - _sqlQuery.CommandText += _currentNodeIndex + ",\'" + _parentConstantId + "\',\'" + with_1.ConstantID + "\',\'" + MiscTools.DBDate(DateTime.Now) + "\')"; - } + var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection); + sqlQuery.ExecuteNonQuery(); + + sqlQuery = new SqlCommand("INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(\'" + MiscTools.PrepareValueForDB(rootTreeNode.Name) + "\', 0, \'" + strProtected + "\'," + ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture) + ")", sqlDatabaseConnector.SqlConnection); + sqlQuery.ExecuteNonQuery(); + } + + private void UpdateConnectionsTable(ContainerInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector) + { + var sqlQuery = new SqlCommand("DELETE FROM tblCons", sqlDatabaseConnector.SqlConnection); + sqlQuery.ExecuteNonQuery(); + var serializer = new DataTableSerializer(SaveSecurity); + var dataTable = serializer.Serialize(rootTreeNode); + var dataProvider = new SqlDataProvider(sqlDatabaseConnector); + dataProvider.Save(dataTable); + } + + private void UpdateUpdatesTable(SqlDatabaseConnector sqlDatabaseConnector) + { + var sqlQuery = new SqlCommand("DELETE FROM tblUpdate", sqlDatabaseConnector.SqlConnection); + sqlQuery.ExecuteNonQuery(); + sqlQuery = new SqlCommand("INSERT INTO tblUpdate (LastUpdate) VALUES(\'" + MiscTools.DBDate(DateTime.Now) + "\')", sqlDatabaseConnector.SqlConnection); + sqlQuery.ExecuteNonQuery(); + } #endregion - - #region XML + private void EncryptCompleteFile() { - StreamReader streamReader = new StreamReader(ConnectionFileName); + var streamReader = new StreamReader(ConnectionFileName); var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - string fileContents; - fileContents = streamReader.ReadToEnd(); + var fileContents = streamReader.ReadToEnd(); streamReader.Close(); - - if (!string.IsNullOrEmpty(fileContents)) - { - StreamWriter streamWriter = new StreamWriter(ConnectionFileName); - streamWriter.Write(cryptographyProvider.Encrypt(fileContents, _password)); - streamWriter.Close(); - } + + if (string.IsNullOrEmpty(fileContents)) return; + var streamWriter = new StreamWriter(ConnectionFileName); + streamWriter.Write(cryptographyProvider.Encrypt(fileContents, _password)); + streamWriter.Close(); } private void SaveToXml() { try { - if (!Runtime.IsConnectionsFileLoaded) + var xmlConnectionsSerializer = new XmlConnectionsSerializer() { - return; - } - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - TreeNode treeNode; + Export = Export, + SaveSecurity = SaveSecurity + }; + var xml = xmlConnectionsSerializer.Serialize(ConnectionTreeModel); - if (ConnectionTreeNode.GetNodeType(RootTreeNode) == TreeNodeType.Root) - { - treeNode = (TreeNode)RootTreeNode.Clone(); - } - else - { - treeNode = new TreeNode("mR|Export (" + MiscTools.DBDate(DateTime.Now) + ")"); - treeNode.Nodes.Add(Convert.ToString(RootTreeNode.Clone())); - } - - string tempFileName = Path.GetTempFileName(); - _xmlTextWriter = new XmlTextWriter(tempFileName, Encoding.UTF8); - - _xmlTextWriter.Formatting = Formatting.Indented; - _xmlTextWriter.Indentation = 4; - - _xmlTextWriter.WriteStartDocument(); - - _xmlTextWriter.WriteStartElement("Connections"); // Do not localize - _xmlTextWriter.WriteAttributeString("Name", "", treeNode.Text); - _xmlTextWriter.WriteAttributeString("Export", "", Convert.ToString(Export)); - - if (Export) - { - _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsNotProtected", _password)); - } - else - { - if (((RootNodeInfo) treeNode.Tag).Password) - { - _password = Convert.ToString(((RootNodeInfo) treeNode.Tag).PasswordString).ConvertToSecureString(); - _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsProtected", _password)); - } - else - { - _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsNotProtected", _password)); - } - } - - _xmlTextWriter.WriteAttributeString("ConfVersion", "", ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture)); - - var treeNodeCollection = treeNode.Nodes; - - SaveNode(treeNodeCollection); - - _xmlTextWriter.WriteEndElement(); - _xmlTextWriter.Close(); - - if (File.Exists(ConnectionFileName)) - { - if (Export) - { - File.Delete(ConnectionFileName); - } - else - { - string backupFileName = ConnectionFileName +".backup"; - File.Delete(backupFileName); - File.Move(ConnectionFileName, backupFileName); - } - } - File.Move(tempFileName, ConnectionFileName); - } + var fileDataProvider = new FileDataProviderWithBackup(ConnectionFileName); + fileDataProvider.Save(xml); + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("SaveToXml failed", ex); } } - private void SaveNode(TreeNodeCollection tNC) + private void SaveToMremotengFormattedCsv() { - try - { - foreach (TreeNode node in tNC) - { - ConnectionInfo curConI; - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) - { - _xmlTextWriter.WriteStartElement("Node"); - _xmlTextWriter.WriteAttributeString("Name", "", node.Text); - _xmlTextWriter.WriteAttributeString("Type", "", ConnectionTreeNode.GetNodeType(node).ToString()); - } - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) //container - { - _xmlTextWriter.WriteAttributeString("Expanded", "", Convert.ToString(ContainerList[node.Tag].TreeNode.IsExpanded)); - curConI = ContainerList[node.Tag]; - SaveConnectionFields(curConI); - SaveNode(node.Nodes); - _xmlTextWriter.WriteEndElement(); - } - - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection) - { - curConI = ConnectionList[node.Tag]; - SaveConnectionFields(curConI); - _xmlTextWriter.WriteEndElement(); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SaveNode failed" + Environment.NewLine + ex.Message, true); - } - } - - private void SaveConnectionFields(ConnectionInfo curConI) - { - try - { - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - _xmlTextWriter.WriteAttributeString("Descr", "", curConI.Description); - - _xmlTextWriter.WriteAttributeString("Icon", "", curConI.Icon); - - _xmlTextWriter.WriteAttributeString("Panel", "", curConI.Panel); - - if (SaveSecurity.Username) - { - _xmlTextWriter.WriteAttributeString("Username", "", curConI.Username); - } - else - { - _xmlTextWriter.WriteAttributeString("Username", "", ""); - } - - if (SaveSecurity.Domain) - { - _xmlTextWriter.WriteAttributeString("Domain", "", curConI.Domain); - } - else - { - _xmlTextWriter.WriteAttributeString("Domain", "", ""); - } - - if (SaveSecurity.Password) - { - _xmlTextWriter.WriteAttributeString("Password", "", cryptographyProvider.Encrypt(curConI.Password, _password)); - } - else - { - _xmlTextWriter.WriteAttributeString("Password", "", ""); - } - - _xmlTextWriter.WriteAttributeString("Hostname", "", curConI.Hostname); - - _xmlTextWriter.WriteAttributeString("Protocol", "", curConI.Protocol.ToString()); - - _xmlTextWriter.WriteAttributeString("PuttySession", "", curConI.PuttySession); - - _xmlTextWriter.WriteAttributeString("Port", "", Convert.ToString(curConI.Port)); - - _xmlTextWriter.WriteAttributeString("ConnectToConsole", "", Convert.ToString(curConI.UseConsoleSession)); - - _xmlTextWriter.WriteAttributeString("UseCredSsp", "", Convert.ToString(curConI.UseCredSsp)); - - _xmlTextWriter.WriteAttributeString("RenderingEngine", "", curConI.RenderingEngine.ToString()); - - _xmlTextWriter.WriteAttributeString("ICAEncryptionStrength", "", curConI.ICAEncryptionStrength.ToString()); - - _xmlTextWriter.WriteAttributeString("RDPAuthenticationLevel", "", curConI.RDPAuthenticationLevel.ToString()); - - _xmlTextWriter.WriteAttributeString("LoadBalanceInfo", "", curConI.LoadBalanceInfo); - - _xmlTextWriter.WriteAttributeString("Colors", "", curConI.Colors.ToString()); - - _xmlTextWriter.WriteAttributeString("Resolution", "", curConI.Resolution.ToString()); - - _xmlTextWriter.WriteAttributeString("AutomaticResize", "", Convert.ToString(curConI.AutomaticResize)); - - _xmlTextWriter.WriteAttributeString("DisplayWallpaper", "", Convert.ToString(curConI.DisplayWallpaper)); - - _xmlTextWriter.WriteAttributeString("DisplayThemes", "", Convert.ToString(curConI.DisplayThemes)); - - _xmlTextWriter.WriteAttributeString("EnableFontSmoothing", "", Convert.ToString(curConI.EnableFontSmoothing)); - - _xmlTextWriter.WriteAttributeString("EnableDesktopComposition", "", Convert.ToString(curConI.EnableDesktopComposition)); - - _xmlTextWriter.WriteAttributeString("CacheBitmaps", "", Convert.ToString(curConI.CacheBitmaps)); - - _xmlTextWriter.WriteAttributeString("RedirectDiskDrives", "", Convert.ToString(curConI.RedirectDiskDrives)); - - _xmlTextWriter.WriteAttributeString("RedirectPorts", "", Convert.ToString(curConI.RedirectPorts)); - - _xmlTextWriter.WriteAttributeString("RedirectPrinters", "", Convert.ToString(curConI.RedirectPrinters)); - - _xmlTextWriter.WriteAttributeString("RedirectSmartCards", "", Convert.ToString(curConI.RedirectSmartCards)); - - _xmlTextWriter.WriteAttributeString("RedirectSound", "", curConI.RedirectSound.ToString()); - - _xmlTextWriter.WriteAttributeString("RedirectKeys", "", Convert.ToString(curConI.RedirectKeys)); - - if (curConI.OpenConnections.Count > 0) - { - _xmlTextWriter.WriteAttributeString("Connected", "", Convert.ToString(true)); - } - else - { - _xmlTextWriter.WriteAttributeString("Connected", "", Convert.ToString(false)); - } - - _xmlTextWriter.WriteAttributeString("PreExtApp", "", curConI.PreExtApp); - _xmlTextWriter.WriteAttributeString("PostExtApp", "", curConI.PostExtApp); - _xmlTextWriter.WriteAttributeString("MacAddress", "", curConI.MacAddress); - _xmlTextWriter.WriteAttributeString("UserField", "", curConI.UserField); - _xmlTextWriter.WriteAttributeString("ExtApp", "", curConI.ExtApp); - - _xmlTextWriter.WriteAttributeString("VNCCompression", "", curConI.VNCCompression.ToString()); - _xmlTextWriter.WriteAttributeString("VNCEncoding", "", curConI.VNCEncoding.ToString()); - _xmlTextWriter.WriteAttributeString("VNCAuthMode", "", curConI.VNCAuthMode.ToString()); - _xmlTextWriter.WriteAttributeString("VNCProxyType", "", curConI.VNCProxyType.ToString()); - _xmlTextWriter.WriteAttributeString("VNCProxyIP", "", curConI.VNCProxyIP); - _xmlTextWriter.WriteAttributeString("VNCProxyPort", "", Convert.ToString(curConI.VNCProxyPort)); - _xmlTextWriter.WriteAttributeString("VNCProxyUsername", "", curConI.VNCProxyUsername); - _xmlTextWriter.WriteAttributeString("VNCProxyPassword", "", cryptographyProvider.Encrypt(curConI.VNCProxyPassword, _password)); - _xmlTextWriter.WriteAttributeString("VNCColors", "", curConI.VNCColors.ToString()); - _xmlTextWriter.WriteAttributeString("VNCSmartSizeMode", "", curConI.VNCSmartSizeMode.ToString()); - _xmlTextWriter.WriteAttributeString("VNCViewOnly", "", Convert.ToString(curConI.VNCViewOnly)); - - _xmlTextWriter.WriteAttributeString("RDGatewayUsageMethod", "", curConI.RDGatewayUsageMethod.ToString()); - _xmlTextWriter.WriteAttributeString("RDGatewayHostname", "", curConI.RDGatewayHostname); - - _xmlTextWriter.WriteAttributeString("RDGatewayUseConnectionCredentials", "", curConI.RDGatewayUseConnectionCredentials.ToString()); - - if (SaveSecurity.Username) - { - _xmlTextWriter.WriteAttributeString("RDGatewayUsername", "", curConI.RDGatewayUsername); - } - else - { - _xmlTextWriter.WriteAttributeString("RDGatewayUsername", "", ""); - } - - if (SaveSecurity.Password) - { - _xmlTextWriter.WriteAttributeString("RDGatewayPassword", "", cryptographyProvider.Encrypt(curConI.RDGatewayPassword, _password)); - } - else - { - _xmlTextWriter.WriteAttributeString("RDGatewayPassword", "", ""); - } - - if (SaveSecurity.Domain) - { - _xmlTextWriter.WriteAttributeString("RDGatewayDomain", "", curConI.RDGatewayDomain); - } - else - { - _xmlTextWriter.WriteAttributeString("RDGatewayDomain", "", ""); - } - - if (SaveSecurity.Inheritance) - { - _xmlTextWriter.WriteAttributeString("InheritCacheBitmaps", "", Convert.ToString(curConI.Inheritance.CacheBitmaps)); - _xmlTextWriter.WriteAttributeString("InheritColors", "", Convert.ToString(curConI.Inheritance.Colors)); - _xmlTextWriter.WriteAttributeString("InheritDescription", "", Convert.ToString(curConI.Inheritance.Description)); - _xmlTextWriter.WriteAttributeString("InheritDisplayThemes", "", Convert.ToString(curConI.Inheritance.DisplayThemes)); - _xmlTextWriter.WriteAttributeString("InheritDisplayWallpaper", "", Convert.ToString(curConI.Inheritance.DisplayWallpaper)); - _xmlTextWriter.WriteAttributeString("InheritEnableFontSmoothing", "", Convert.ToString(curConI.Inheritance.EnableFontSmoothing)); - _xmlTextWriter.WriteAttributeString("InheritEnableDesktopComposition", "", Convert.ToString(curConI.Inheritance.EnableDesktopComposition)); - _xmlTextWriter.WriteAttributeString("InheritDomain", "", Convert.ToString(curConI.Inheritance.Domain)); - _xmlTextWriter.WriteAttributeString("InheritIcon", "", Convert.ToString(curConI.Inheritance.Icon)); - _xmlTextWriter.WriteAttributeString("InheritPanel", "", Convert.ToString(curConI.Inheritance.Panel)); - _xmlTextWriter.WriteAttributeString("InheritPassword", "", Convert.ToString(curConI.Inheritance.Password)); - _xmlTextWriter.WriteAttributeString("InheritPort", "", Convert.ToString(curConI.Inheritance.Port)); - _xmlTextWriter.WriteAttributeString("InheritProtocol", "", Convert.ToString(curConI.Inheritance.Protocol)); - _xmlTextWriter.WriteAttributeString("InheritPuttySession", "", Convert.ToString(curConI.Inheritance.PuttySession)); - _xmlTextWriter.WriteAttributeString("InheritRedirectDiskDrives", "", Convert.ToString(curConI.Inheritance.RedirectDiskDrives)); - _xmlTextWriter.WriteAttributeString("InheritRedirectKeys", "", Convert.ToString(curConI.Inheritance.RedirectKeys)); - _xmlTextWriter.WriteAttributeString("InheritRedirectPorts", "", Convert.ToString(curConI.Inheritance.RedirectPorts)); - _xmlTextWriter.WriteAttributeString("InheritRedirectPrinters", "", Convert.ToString(curConI.Inheritance.RedirectPrinters)); - _xmlTextWriter.WriteAttributeString("InheritRedirectSmartCards", "", Convert.ToString(curConI.Inheritance.RedirectSmartCards)); - _xmlTextWriter.WriteAttributeString("InheritRedirectSound", "", Convert.ToString(curConI.Inheritance.RedirectSound)); - _xmlTextWriter.WriteAttributeString("InheritResolution", "", Convert.ToString(curConI.Inheritance.Resolution)); - _xmlTextWriter.WriteAttributeString("InheritAutomaticResize", "", Convert.ToString(curConI.Inheritance.AutomaticResize)); - _xmlTextWriter.WriteAttributeString("InheritUseConsoleSession", "", Convert.ToString(curConI.Inheritance.UseConsoleSession)); - _xmlTextWriter.WriteAttributeString("InheritUseCredSsp", "", Convert.ToString(curConI.Inheritance.UseCredSsp)); - _xmlTextWriter.WriteAttributeString("InheritRenderingEngine", "", Convert.ToString(curConI.Inheritance.RenderingEngine)); - _xmlTextWriter.WriteAttributeString("InheritUsername", "", Convert.ToString(curConI.Inheritance.Username)); - _xmlTextWriter.WriteAttributeString("InheritICAEncryptionStrength", "", Convert.ToString(curConI.Inheritance.ICAEncryptionStrength)); - _xmlTextWriter.WriteAttributeString("InheritRDPAuthenticationLevel", "", Convert.ToString(curConI.Inheritance.RDPAuthenticationLevel)); - _xmlTextWriter.WriteAttributeString("InheritLoadBalanceInfo", "", Convert.ToString(curConI.Inheritance.LoadBalanceInfo)); - _xmlTextWriter.WriteAttributeString("InheritPreExtApp", "", Convert.ToString(curConI.Inheritance.PreExtApp)); - _xmlTextWriter.WriteAttributeString("InheritPostExtApp", "", Convert.ToString(curConI.Inheritance.PostExtApp)); - _xmlTextWriter.WriteAttributeString("InheritMacAddress", "", Convert.ToString(curConI.Inheritance.MacAddress)); - _xmlTextWriter.WriteAttributeString("InheritUserField", "", Convert.ToString(curConI.Inheritance.UserField)); - _xmlTextWriter.WriteAttributeString("InheritExtApp", "", Convert.ToString(curConI.Inheritance.ExtApp)); - _xmlTextWriter.WriteAttributeString("InheritVNCCompression", "", Convert.ToString(curConI.Inheritance.VNCCompression)); - _xmlTextWriter.WriteAttributeString("InheritVNCEncoding", "", Convert.ToString(curConI.Inheritance.VNCEncoding)); - _xmlTextWriter.WriteAttributeString("InheritVNCAuthMode", "", Convert.ToString(curConI.Inheritance.VNCAuthMode)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyType", "", Convert.ToString(curConI.Inheritance.VNCProxyType)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyIP", "", Convert.ToString(curConI.Inheritance.VNCProxyIP)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyPort", "", Convert.ToString(curConI.Inheritance.VNCProxyPort)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyUsername", "", Convert.ToString(curConI.Inheritance.VNCProxyUsername)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyPassword", "", Convert.ToString(curConI.Inheritance.VNCProxyPassword)); - _xmlTextWriter.WriteAttributeString("InheritVNCColors", "", Convert.ToString(curConI.Inheritance.VNCColors)); - _xmlTextWriter.WriteAttributeString("InheritVNCSmartSizeMode", "", Convert.ToString(curConI.Inheritance.VNCSmartSizeMode)); - _xmlTextWriter.WriteAttributeString("InheritVNCViewOnly", "", Convert.ToString(curConI.Inheritance.VNCViewOnly)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsageMethod", "", Convert.ToString(curConI.Inheritance.RDGatewayUsageMethod)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayHostname", "", Convert.ToString(curConI.Inheritance.RDGatewayHostname)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayUseConnectionCredentials", "", Convert.ToString(curConI.Inheritance.RDGatewayUseConnectionCredentials)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsername", "", Convert.ToString(curConI.Inheritance.RDGatewayUsername)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayPassword", "", Convert.ToString(curConI.Inheritance.RDGatewayPassword)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayDomain", "", Convert.ToString(curConI.Inheritance.RDGatewayDomain)); - } - else - { - _xmlTextWriter.WriteAttributeString("InheritCacheBitmaps", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritColors", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritDescription", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritDisplayThemes", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritDisplayWallpaper", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritEnableFontSmoothing", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritEnableDesktopComposition", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritDomain", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritIcon", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPanel", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPassword", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPort", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritProtocol", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPuttySession", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectDiskDrives", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectKeys", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectPorts", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectPrinters", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectSmartCards", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRedirectSound", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritResolution", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritAutomaticResize", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritUseConsoleSession", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritUseCredSsp", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRenderingEngine", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritUsername", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritICAEncryptionStrength", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDPAuthenticationLevel", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritLoadBalanceInfo", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPreExtApp", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritPostExtApp", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritMacAddress", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritUserField", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritExtApp", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCCompression", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCEncoding", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCAuthMode", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyType", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyIP", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyPort", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyUsername", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCProxyPassword", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCColors", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCSmartSizeMode", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritVNCViewOnly", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayHostname", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayUseConnectionCredentials", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsername", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayPassword", "", Convert.ToString(false)); - _xmlTextWriter.WriteAttributeString("InheritRDGatewayDomain", "", Convert.ToString(false)); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SaveConnectionFields failed" + Environment.NewLine + ex.Message, true); - } - } - #endregion - - #region CSV - private StreamWriter csvWr; - - private void SaveTomRCSV() - { - if (Runtime.IsConnectionsFileLoaded == false) - { - return; - } + var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat { SaveSecurity = SaveSecurity }; + var dataProvider = new FileDataProvider(ConnectionFileName); + var csvContent = csvConnectionsSerializer.Serialize(ConnectionTreeModel); + dataProvider.Save(csvContent); + } - var tN = (TreeNode)RootTreeNode.Clone(); - - var tNC = tN.Nodes; - - csvWr = new StreamWriter(ConnectionFileName); - - - string csvLn = string.Empty; - - csvLn += "Name;Folder;Description;Icon;Panel;"; - - if (SaveSecurity.Username) - { - csvLn += "Username;"; - } - - if (SaveSecurity.Password) - { - csvLn += "Password;"; - } - - if (SaveSecurity.Domain) - { - csvLn += "Domain;"; - } - - csvLn += "Hostname;Protocol;PuttySession;Port;ConnectToConsole;UseCredSsp;RenderingEngine;ICAEncryptionStrength;RDPAuthenticationLevel;LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectSmartCards;RedirectSound;RedirectKeys;PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;"; - - if (SaveSecurity.Inheritance) - { - csvLn += "InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;InheritProtocol;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;InheritUseConsoleSession;InheritUseCredSsp;InheritRenderingEngine;InheritUsername;InheritICAEncryptionStrength;InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;InheritRDGatewayPassword;InheritRDGatewayDomain"; - } - - csvWr.WriteLine(csvLn); - - SaveNodemRCSV(tNC); - - csvWr.Close(); - } - - private void SaveNodemRCSV(TreeNodeCollection tNC) - { - foreach (TreeNode node in tNC) - { - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection) - { - ConnectionInfo curConI = (ConnectionInfo)node.Tag; - - WritemRCSVLine(curConI); - } - else if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) - { - SaveNodemRCSV(node.Nodes); - } - } - } - - private void WritemRCSVLine(ConnectionInfo con) - { - string nodePath = con.TreeNode.FullPath; - - int firstSlash = nodePath.IndexOf("\\", StringComparison.Ordinal); - nodePath = nodePath.Remove(0, firstSlash + 1); - int lastSlash = nodePath.LastIndexOf("\\", StringComparison.Ordinal); - - if (lastSlash > 0) - { - nodePath = nodePath.Remove(lastSlash); - } - else - { - nodePath = ""; - } - - string csvLn = string.Empty; - - csvLn += con.Name + ";" + nodePath + ";" + con.Description + ";" + con.Icon + ";" + con.Panel + ";"; - - if (SaveSecurity.Username) - { - csvLn += con.Username + ";"; - } - - if (SaveSecurity.Password) - { - csvLn += con.Password + ";"; - } - - if (SaveSecurity.Domain) - { - csvLn += con.Domain + ";"; - } - - csvLn += con.Hostname + ";" + con.Protocol + ";" + con.PuttySession + ";" + Convert.ToString(con.Port) + ";" + Convert.ToString(con.UseConsoleSession) + ";" + Convert.ToString(con.UseCredSsp) + ";" + con.RenderingEngine + ";" + con.ICAEncryptionStrength + ";" + con.RDPAuthenticationLevel + ";" + con.LoadBalanceInfo + ";" + con.Colors + ";" + con.Resolution + ";" + Convert.ToString(con.AutomaticResize) + ";" + Convert.ToString(con.DisplayWallpaper) + ";" + Convert.ToString(con.DisplayThemes) + ";" + Convert.ToString(con.EnableFontSmoothing) + ";" + Convert.ToString(con.EnableDesktopComposition) + ";" + Convert.ToString(con.CacheBitmaps) + ";" + Convert.ToString(con.RedirectDiskDrives) + ";" + Convert.ToString(con.RedirectPorts) + ";" + Convert.ToString(con.RedirectPrinters) + ";" + Convert.ToString(con.RedirectSmartCards) + ";" + con.RedirectSound + ";" + Convert.ToString(con.RedirectKeys) + ";" + con.PreExtApp + ";" + con.PostExtApp + ";" + con.MacAddress + ";" + con.UserField + ";" + con.ExtApp + ";" + con.VNCCompression + ";" + con.VNCEncoding + ";" + con.VNCAuthMode + ";" + con.VNCProxyType + ";" + con.VNCProxyIP + ";" + Convert.ToString(con.VNCProxyPort) + ";" + con.VNCProxyUsername + ";" + con.VNCProxyPassword + ";" + con.VNCColors + ";" + con.VNCSmartSizeMode + ";" + Convert.ToString(con.VNCViewOnly) + ";"; - - if (SaveSecurity.Inheritance) - { - csvLn += con.Inheritance.CacheBitmaps + ";" + Convert.ToString(con.Inheritance.Colors) + ";" + Convert.ToString(con.Inheritance.Description) + ";" + Convert.ToString(con.Inheritance.DisplayThemes) + ";" + Convert.ToString(con.Inheritance.DisplayWallpaper) + ";" + Convert.ToString(con.Inheritance.EnableFontSmoothing) + ";" + Convert.ToString(con.Inheritance.EnableDesktopComposition) + ";" + Convert.ToString(con.Inheritance.Domain) + ";" + Convert.ToString(con.Inheritance.Icon) + ";" + Convert.ToString(con.Inheritance.Panel) + ";" + Convert.ToString(con.Inheritance.Password) + ";" + Convert.ToString(con.Inheritance.Port) + ";" + Convert.ToString(con.Inheritance.Protocol) + ";" + Convert.ToString(con.Inheritance.PuttySession) + ";" + Convert.ToString(con.Inheritance.RedirectDiskDrives) + ";" + Convert.ToString(con.Inheritance.RedirectKeys) + ";" + Convert.ToString(con.Inheritance.RedirectPorts) + ";" + Convert.ToString(con.Inheritance.RedirectPrinters) + ";" + Convert.ToString(con.Inheritance.RedirectSmartCards) + ";" + Convert.ToString(con.Inheritance.RedirectSound) + ";" + Convert.ToString(con.Inheritance.Resolution) + ";" + Convert.ToString(con.Inheritance.AutomaticResize) + ";" + Convert.ToString(con.Inheritance.UseConsoleSession) + ";" + Convert.ToString(con.Inheritance.UseCredSsp) + ";" + Convert.ToString(con.Inheritance.RenderingEngine) + ";" + Convert.ToString(con.Inheritance.Username) + ";" + Convert.ToString(con.Inheritance.ICAEncryptionStrength) + ";" + Convert.ToString(con.Inheritance.RDPAuthenticationLevel) + ";" + Convert.ToString(con.Inheritance.LoadBalanceInfo) + ";" + Convert.ToString(con.Inheritance.PreExtApp) + ";" + Convert.ToString(con.Inheritance.PostExtApp) + ";" + Convert.ToString(con.Inheritance.MacAddress) + ";" + Convert.ToString(con.Inheritance.UserField) + ";" + Convert.ToString(con.Inheritance.ExtApp) + ";" + Convert.ToString(con.Inheritance.VNCCompression) + ";" - + Convert.ToString(con.Inheritance.VNCEncoding) + ";" + Convert.ToString(con.Inheritance.VNCAuthMode) + ";" + Convert.ToString(con.Inheritance.VNCProxyType) + ";" + Convert.ToString(con.Inheritance.VNCProxyIP) + ";" + Convert.ToString(con.Inheritance.VNCProxyPort) + ";" + Convert.ToString(con.Inheritance.VNCProxyUsername) + ";" + Convert.ToString(con.Inheritance.VNCProxyPassword) + ";" + Convert.ToString(con.Inheritance.VNCColors) + ";" + Convert.ToString(con.Inheritance.VNCSmartSizeMode) + ";" + Convert.ToString(con.Inheritance.VNCViewOnly); - } - - csvWr.WriteLine(csvLn); - } - #endregion - - #region vRD CSV - private void SaveTovRDCSV() - { - if (Runtime.IsConnectionsFileLoaded == false) - { - return; - } - - var tN = (TreeNode)RootTreeNode.Clone(); - - var tNC = tN.Nodes; - - csvWr = new StreamWriter(ConnectionFileName); - - SaveNodevRDCSV(tNC); - - csvWr.Close(); - } - - private void SaveNodevRDCSV(TreeNodeCollection tNC) - { - foreach (TreeNode node in tNC) - { - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection) - { - ConnectionInfo curConI = (ConnectionInfo)node.Tag; - - if (curConI.Protocol == ProtocolType.RDP) - { - WritevRDCSVLine(curConI); - } - } - else if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Container) - { - SaveNodevRDCSV(node.Nodes); - } - } - } - - private void WritevRDCSVLine(ConnectionInfo con) - { - string nodePath = con.TreeNode.FullPath; - - int firstSlash = nodePath.IndexOf("\\", StringComparison.Ordinal); - nodePath = nodePath.Remove(0, firstSlash + 1); - int lastSlash = nodePath.LastIndexOf("\\", StringComparison.Ordinal); - - if (lastSlash > 0) - { - nodePath = nodePath.Remove(lastSlash); - } - else - { - nodePath = ""; - } - - csvWr.WriteLine(con.Name + ";" + con.Hostname + ";" + con.MacAddress + ";;" + Convert.ToString(con.Port) + ";" + Convert.ToString(con.UseConsoleSession) + ";" + nodePath); - } - #endregion + private void SaveToRemoteDesktop2008FormattedCsv() + { + var csvSerializer = new CsvConnectionsSerializerRemoteDesktop2008Format(); + var dataProvider = new FileDataProvider(ConnectionFileName); + var csvContent = csvSerializer.Serialize(ConnectionTreeModel); + dataProvider.Save(csvContent); + } #region vRD VRE + // .VRE files are for ASG-Remote Desktop (prevously visionapp Remote Desktop) private void SaveToVRE() { if (Runtime.IsConnectionsFileLoaded == false) @@ -1140,7 +323,7 @@ namespace mRemoteNG.Config.Connections { foreach (TreeNode node in tNC) { - if (ConnectionTreeNode.GetNodeType(node) == TreeNodeType.Connection) + if (((ConnectionInfo)node.Tag).GetTreeNodeType() == TreeNodeType.Connection) { ConnectionInfo curConI = (ConnectionInfo)node.Tag; diff --git a/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateAvailableEventArgs.cs b/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateAvailableEventArgs.cs new file mode 100644 index 000000000..09e8ed841 --- /dev/null +++ b/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateAvailableEventArgs.cs @@ -0,0 +1,21 @@ +using System; +using mRemoteNG.Config.DatabaseConnectors; + + +namespace mRemoteNG.Config.Connections +{ + public delegate void ConnectionsUpdateAvailableEventHandler(object sender, ConnectionsUpdateAvailableEventArgs args); + + public class ConnectionsUpdateAvailableEventArgs : EventArgs + { + public IDatabaseConnector DatabaseConnector { get; private set; } + public DateTime UpdateTime { get; private set; } + public bool Handled { get; set; } + + public ConnectionsUpdateAvailableEventArgs(IDatabaseConnector databaseConnector, DateTime updateTime) + { + DatabaseConnector = databaseConnector; + UpdateTime = updateTime; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateCheckFinishedEventArgs.cs b/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateCheckFinishedEventArgs.cs new file mode 100644 index 000000000..0b6072408 --- /dev/null +++ b/mRemoteV1/Config/Connections/Multiuser/ConnectionsUpdateCheckFinishedEventArgs.cs @@ -0,0 +1,12 @@ +using System; + + +namespace mRemoteNG.Config.Connections +{ + public delegate void UpdateCheckFinishedEventHandler(object sender, ConnectionsUpdateCheckFinishedEventArgs args); + + public class ConnectionsUpdateCheckFinishedEventArgs : EventArgs + { + public bool UpdateAvailable { get; set; } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/Multiuser/IConnectionsUpdateChecker.cs b/mRemoteV1/Config/Connections/Multiuser/IConnectionsUpdateChecker.cs new file mode 100644 index 000000000..e80b657f9 --- /dev/null +++ b/mRemoteV1/Config/Connections/Multiuser/IConnectionsUpdateChecker.cs @@ -0,0 +1,16 @@ +using System; + + +namespace mRemoteNG.Config.Connections +{ + public interface IConnectionsUpdateChecker : IDisposable + { + bool IsUpdateAvailable(); + + void IsUpdateAvailableAsync(); + + event EventHandler UpdateCheckStarted; + event UpdateCheckFinishedEventHandler UpdateCheckFinished; + event ConnectionsUpdateAvailableEventHandler ConnectionsUpdateAvailable; + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs new file mode 100644 index 000000000..44e720cce --- /dev/null +++ b/mRemoteV1/Config/Connections/Multiuser/RemoteConnectionsSyncronizer.cs @@ -0,0 +1,89 @@ +using System; +using System.Timers; +using mRemoteNG.App; + + +namespace mRemoteNG.Config.Connections +{ + public class RemoteConnectionsSyncronizer : IConnectionsUpdateChecker + { + private readonly Timer _updateTimer; + private readonly IConnectionsUpdateChecker _updateChecker; + private readonly ConnectionsLoader _connectionsLoader; + private readonly ConnectionsSaver _connectionsSaver; + + public double TimerIntervalInMilliseconds => _updateTimer.Interval; + + public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker) + { + _updateChecker = updateChecker; + _updateTimer = new Timer(3000); + _connectionsLoader = new ConnectionsLoader { UseDatabase = mRemoteNG.Settings.Default.UseSQLServer }; + _connectionsSaver = new ConnectionsSaver { SaveFormat = ConnectionsSaver.Format.SQL }; + SetEventListeners(); + } + + private void SetEventListeners() + { + _updateChecker.UpdateCheckStarted += OnUpdateCheckStarted; + _updateChecker.UpdateCheckFinished += OnUpdateCheckFinished; + _updateChecker.ConnectionsUpdateAvailable += (sender, args) => ConnectionsUpdateAvailable?.Invoke(sender, args); + _updateTimer.Elapsed += (sender, args) => _updateChecker.IsUpdateAvailableAsync(); + ConnectionsUpdateAvailable += Load; + } + + public void Load() + { + Runtime.ConnectionTreeModel = _connectionsLoader.LoadConnections(false); + } + + private void Load(object sender, ConnectionsUpdateAvailableEventArgs args) + { + Load(); + args.Handled = true; + } + + public void Save() + { + _connectionsSaver.SaveConnections(); + } + + public void Enable() => _updateTimer.Start(); + public void Disable() => _updateTimer.Stop(); + public bool IsUpdateAvailable() => _updateChecker.IsUpdateAvailable(); + public void IsUpdateAvailableAsync() => _updateChecker.IsUpdateAvailableAsync(); + + + private void OnUpdateCheckStarted(object sender, EventArgs eventArgs) + { + _updateTimer.Stop(); + UpdateCheckStarted?.Invoke(sender, eventArgs); + } + + private void OnUpdateCheckFinished(object sender, ConnectionsUpdateCheckFinishedEventArgs eventArgs) + { + _updateTimer.Start(); + UpdateCheckFinished?.Invoke(sender, eventArgs); + } + + public event EventHandler UpdateCheckStarted; + public event UpdateCheckFinishedEventHandler UpdateCheckFinished; + public event ConnectionsUpdateAvailableEventHandler ConnectionsUpdateAvailable; + + ~RemoteConnectionsSyncronizer() + { + Dispose(false); + } + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + private void Dispose(bool itIsSafeToAlsoFreeManagedObjects) + { + if (!itIsSafeToAlsoFreeManagedObjects) return; + _updateTimer.Dispose(); + _updateChecker.Dispose(); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/Multiuser/SqlConnectionsUpdateChecker.cs b/mRemoteV1/Config/Connections/Multiuser/SqlConnectionsUpdateChecker.cs new file mode 100644 index 000000000..eb9f26456 --- /dev/null +++ b/mRemoteV1/Config/Connections/Multiuser/SqlConnectionsUpdateChecker.cs @@ -0,0 +1,122 @@ +using mRemoteNG.App; +using mRemoteNG.Messages; +using System; +using System.Data; +using System.Data.SqlClient; +using System.Threading; +using mRemoteNG.Config.DatabaseConnectors; + +namespace mRemoteNG.Config.Connections +{ + public class SqlConnectionsUpdateChecker : IConnectionsUpdateChecker + { + private readonly SqlDatabaseConnector _sqlConnector; + private readonly SqlCommand _sqlQuery; + private DateTime _lastUpdateTime; + private DateTime _lastDatabaseUpdateTime; + + + public SqlConnectionsUpdateChecker() + { + _sqlConnector = new SqlDatabaseConnector(); + _sqlQuery = new SqlCommand("SELECT * FROM tblUpdate", _sqlConnector.SqlConnection); + _lastUpdateTime = default(DateTime); + _lastDatabaseUpdateTime = default(DateTime); + } + + public bool IsUpdateAvailable() + { + RaiseUpdateCheckStartedEvent(); + ConnectToSqlDb(); + var updateIsAvailable = DatabaseIsMoreUpToDateThanUs(); + if (updateIsAvailable) + RaiseConnectionsUpdateAvailableEvent(); + RaiseUpdateCheckFinishedEvent(updateIsAvailable); + return updateIsAvailable; + } + + public void IsUpdateAvailableAsync() + { + var thread = new Thread(() => IsUpdateAvailable()); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + } + + private void ConnectToSqlDb() + { + try + { + _sqlConnector.Connect(); + } + catch(Exception e) + { + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Unable to connect to Sql DB to check for updates." + Environment.NewLine + e.Message, true); + } + } + + private bool DatabaseIsMoreUpToDateThanUs() + { + return GetLastUpdateTimeFromDbResponse() > _lastUpdateTime; + } + + private DateTime GetLastUpdateTimeFromDbResponse() + { + var lastUpdateInDb = default(DateTime); + try + { + var sqlReader = _sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); + sqlReader.Read(); + if (sqlReader.HasRows) + lastUpdateInDb = Convert.ToDateTime(sqlReader["LastUpdate"]); + sqlReader.Close(); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Error executing Sql query to get updates from the DB." + Environment.NewLine + ex.Message, true); + } + _lastDatabaseUpdateTime = lastUpdateInDb; + return lastUpdateInDb; + } + + + public event EventHandler UpdateCheckStarted; + private void RaiseUpdateCheckStartedEvent() + { + UpdateCheckStarted?.Invoke(this, EventArgs.Empty); + } + + public event UpdateCheckFinishedEventHandler UpdateCheckFinished; + private void RaiseUpdateCheckFinishedEvent(bool updateAvailable) + { + var args = new ConnectionsUpdateCheckFinishedEventArgs {UpdateAvailable = updateAvailable}; + UpdateCheckFinished?.Invoke(this, args); + } + + public event ConnectionsUpdateAvailableEventHandler ConnectionsUpdateAvailable; + private void RaiseConnectionsUpdateAvailableEvent() + { + var args = new ConnectionsUpdateAvailableEventArgs(_sqlConnector, _lastDatabaseUpdateTime); + ConnectionsUpdateAvailable?.Invoke(this, args); + if(args.Handled) + _lastUpdateTime = _lastDatabaseUpdateTime; + } + + + ~SqlConnectionsUpdateChecker() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + } + + private void Dispose(bool itIsSafeToDisposeManagedObjects) + { + if (!itIsSafeToDisposeManagedObjects) return; + _sqlConnector.Disconnect(); + _sqlConnector.Dispose(); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SQLConnectionsProvider.cs b/mRemoteV1/Config/Connections/SQLConnectionsProvider.cs deleted file mode 100644 index 182b137a2..000000000 --- a/mRemoteV1/Config/Connections/SQLConnectionsProvider.cs +++ /dev/null @@ -1,72 +0,0 @@ -using mRemoteNG.App; -using mRemoteNG.Messages; -using System; - -namespace mRemoteNG.Config.Connections -{ - public class SqlConnectionsProvider : IDisposable - { - SqlUpdateTimer _updateTimer; - SqlConnectionsUpdateChecker _sqlUpdateChecker; - - - public SqlConnectionsProvider() - { - _updateTimer = new SqlUpdateTimer(); - _sqlUpdateChecker = new SqlConnectionsUpdateChecker(); - SqlUpdateTimer.SqlUpdateTimerElapsed += SqlUpdateTimer_SqlUpdateTimerElapsed; - SqlConnectionsUpdateChecker.SQLUpdateCheckFinished += SQLUpdateCheckFinished; - } - - ~SqlConnectionsProvider() - { - Dispose(false); - } - - public void Enable() - { - _updateTimer.Enable(); - } - - public void Disable() - { - _updateTimer.Disable(); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool itIsSafeToAlsoFreeManagedObjects) - { - if (itIsSafeToAlsoFreeManagedObjects) - { - DestroySQLUpdateHandlers(); - _updateTimer.Dispose(); - _sqlUpdateChecker.Dispose(); - } - } - - private void DestroySQLUpdateHandlers() - { - SqlUpdateTimer.SqlUpdateTimerElapsed -= SqlUpdateTimer_SqlUpdateTimerElapsed; - SqlConnectionsUpdateChecker.SQLUpdateCheckFinished -= SQLUpdateCheckFinished; - } - - private void SqlUpdateTimer_SqlUpdateTimerElapsed() - { - _sqlUpdateChecker.IsDatabaseUpdateAvailableAsync(); - } - - private void SQLUpdateCheckFinished(bool UpdateIsAvailable) - { - if (UpdateIsAvailable) - { - Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strSqlUpdateCheckUpdateAvailable, true); - Runtime.LoadConnectionsBG(); - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SqlCommandBuilder.cs b/mRemoteV1/Config/Connections/SqlCommandBuilder.cs deleted file mode 100644 index 8f5f9a837..000000000 --- a/mRemoteV1/Config/Connections/SqlCommandBuilder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Data.SqlClient; - -namespace mRemoteNG.Config.Connections -{ - public interface SqlCommandBuilder - { - SqlCommand BuildCommand(); - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs b/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs deleted file mode 100644 index 746693d3f..000000000 --- a/mRemoteV1/Config/Connections/SqlConnectionsLoader.cs +++ /dev/null @@ -1,510 +0,0 @@ -using System; -using System.Data; -using System.Data.SqlClient; -using System.Globalization; -using System.Security; -using System.Windows.Forms; -using mRemoteNG.App; -using mRemoteNG.App.Info; -using mRemoteNG.Connection; -using mRemoteNG.Connection.Protocol; -using mRemoteNG.Connection.Protocol.Http; -using mRemoteNG.Connection.Protocol.ICA; -using mRemoteNG.Connection.Protocol.RDP; -using mRemoteNG.Connection.Protocol.VNC; -using mRemoteNG.Container; -using mRemoteNG.Messages; -using mRemoteNG.Security; -using mRemoteNG.Security.SymmetricEncryption; -using mRemoteNG.Tree; -using mRemoteNG.Tree.Root; -using mRemoteNG.UI.Forms; -using mRemoteNG.UI.TaskDialog; - -namespace mRemoteNG.Config.Connections -{ - public class SqlConnectionsLoader - { - private SqlConnection _sqlConnection; - private SqlCommand _sqlQuery; - private SqlDataReader _sqlDataReader; - private TreeNode _selectedTreeNode; - private double _confVersion; - private SecureString _pW = GeneralAppInfo.EncryptionKey; - - - public string DatabaseHost { get; set; } - public string DatabaseName { get; set; } - public string DatabaseUsername { get; set; } - public string DatabasePassword { get; set; } - public bool DatabaseUpdate { get; set; } - public string PreviousSelected { get; set; } - public TreeNode RootTreeNode { get; set; } - public ConnectionList ConnectionList { get; set; } - public ContainerList ContainerList { get; set; } - public ConnectionList PreviousConnectionList { get; set; } - public ContainerList PreviousContainerList { get; set; } - - - private delegate void LoadFromSqlDelegate(); - public void LoadFromSql() - { - if (Windows.treeForm == null || Windows.treeForm.tvConnections == null) - return; - if (Windows.treeForm.tvConnections.InvokeRequired) - { - Windows.treeForm.tvConnections.Invoke(new LoadFromSqlDelegate(LoadFromSql)); - return; - } - - try - { - Runtime.IsConnectionsFileLoaded = false; - _sqlConnection = !string.IsNullOrEmpty(DatabaseUsername) ? new SqlConnection("Data Source=" + DatabaseHost + ";Initial Catalog=" + DatabaseName + ";User Id=" + DatabaseUsername + ";Password=" + DatabasePassword) : new SqlConnection("Data Source=" + DatabaseHost + ";Initial Catalog=" + DatabaseName + ";Integrated Security=True"); - - _sqlConnection.Open(); - _sqlQuery = new SqlCommand("SELECT * FROM tblRoot", _sqlConnection); - _sqlDataReader = _sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); - _sqlDataReader.Read(); - - if (_sqlDataReader.HasRows == false) - { - Runtime.SaveConnections(); - _sqlQuery = new SqlCommand("SELECT * FROM tblRoot", _sqlConnection); - _sqlDataReader = _sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); - _sqlDataReader.Read(); - } - - _confVersion = Convert.ToDouble(_sqlDataReader["confVersion"], CultureInfo.InvariantCulture); - const double maxSupportedSchemaVersion = 2.5; - if (_confVersion > maxSupportedSchemaVersion) - { - CTaskDialog.ShowTaskDialogBox( - frmMain.Default, - Application.ProductName, - "Incompatible database schema", - $"The database schema on the server is not supported. Please upgrade to a newer version of {Application.ProductName}.", - string.Format("Schema Version: {1}{0}Highest Supported Version: {2}", Environment.NewLine, _confVersion, maxSupportedSchemaVersion), - "", - "", - "", - "", - ETaskDialogButtons.Ok, - ESysIcons.Error, - ESysIcons.Error - ); - throw (new Exception($"Incompatible database schema (schema version {_confVersion}).")); - } - - RootTreeNode.Name = Convert.ToString(_sqlDataReader["Name"]); - - var rootInfo = new RootNodeInfo(RootNodeType.Connection) - { - Name = RootTreeNode.Name, - TreeNode = RootTreeNode - }; - - RootTreeNode.Tag = rootInfo; - RootTreeNode.ImageIndex = (int)TreeImageType.Root; - RootTreeNode.SelectedImageIndex = (int)TreeImageType.Root; - - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - if (cryptographyProvider.Decrypt(Convert.ToString(_sqlDataReader["Protected"]), _pW) != "ThisIsNotProtected") - { - if (Authenticate(Convert.ToString(_sqlDataReader["Protected"]), false, rootInfo) == false) - { - mRemoteNG.Settings.Default.LoadConsFromCustomLocation = false; - mRemoteNG.Settings.Default.CustomConsPath = ""; - RootTreeNode.Remove(); - return; - } - } - - _sqlDataReader.Close(); - Windows.treeForm.tvConnections.BeginUpdate(); - - // SECTION 3. Populate the TreeView with the DOM nodes. - AddNodesFromSql(RootTreeNode); - RootTreeNode.Expand(); - - //expand containers - foreach (ContainerInfo contI in ContainerList) - { - if (contI.IsExpanded) - contI.TreeNode.Expand(); - } - - Windows.treeForm.tvConnections.EndUpdate(); - - //open connections from last mremote session - if (mRemoteNG.Settings.Default.OpenConsFromLastSession && !mRemoteNG.Settings.Default.NoReconnect) - { - foreach (ConnectionInfo conI in ConnectionList) - { - if (conI.PleaseConnect) - Runtime.OpenConnection(conI); - } - } - - Runtime.IsConnectionsFileLoaded = true; - Windows.treeForm.InitialRefresh(); - SetSelectedNode(_selectedTreeNode); - } - finally - { - _sqlConnection?.Close(); - } - } - - private void AddNodesFromSql(TreeNode baseNode) - { - try - { - _sqlConnection.Open(); - _sqlQuery = new SqlCommand("SELECT * FROM tblCons ORDER BY PositionID ASC", _sqlConnection); - _sqlDataReader = _sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); - - if (_sqlDataReader.HasRows == false) - return; - - while (_sqlDataReader.Read()) - { - var tNode = new TreeNode(Convert.ToString(_sqlDataReader["Name"])); - var nodeType = ConnectionTreeNode.GetNodeTypeFromString(Convert.ToString(_sqlDataReader["Type"])); - - if (nodeType == TreeNodeType.Connection) - AddConnectionToList(tNode); - else if (nodeType == TreeNodeType.Container) - AddContainerToList(tNode); - - var parentId = Convert.ToString(_sqlDataReader["ParentID"].ToString().Trim()); - if (string.IsNullOrEmpty(parentId) || parentId == "0") - { - baseNode.Nodes.Add(tNode); - } - else - { - var pNode = ConnectionTreeNode.GetNodeFromConstantID(Convert.ToString(_sqlDataReader["ParentID"])); - if (pNode != null) - { - pNode.Nodes.Add(tNode); - - switch (ConnectionTreeNode.GetNodeType(tNode)) - { - case TreeNodeType.Connection: - ((ConnectionInfo) tNode.Tag).Parent = (ContainerInfo)pNode.Tag; - break; - case TreeNodeType.Container: - ((ContainerInfo) tNode.Tag).Parent = (ContainerInfo)pNode.Tag; - break; - } - } - else - { - baseNode.Nodes.Add(tNode); - } - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strAddNodesFromSqlFailed + Environment.NewLine + ex.Message, true); - } - } - - private void AddConnectionToList(TreeNode tNode) - { - var conI = GetConnectionInfoFromSql(); - conI.TreeNode = tNode; - ConnectionList.Add(conI); - tNode.Tag = conI; - - if (DatabaseUpdate) - { - var prevCon = PreviousConnectionList.FindByConstantID(conI.ConstantID); - if (prevCon != null) - { - foreach (ProtocolBase prot in prevCon.OpenConnections) - { - prot.InterfaceControl.Info = conI; - conI.OpenConnections.Add(prot); - } - - if (conI.OpenConnections.Count > 0) - { - tNode.ImageIndex = (int) TreeImageType.ConnectionOpen; - tNode.SelectedImageIndex = (int) TreeImageType.ConnectionOpen; - } - else - { - tNode.ImageIndex = (int) TreeImageType.ConnectionClosed; - tNode.SelectedImageIndex = (int) TreeImageType.ConnectionClosed; - } - } - else - { - tNode.ImageIndex = (int) TreeImageType.ConnectionClosed; - tNode.SelectedImageIndex = (int) TreeImageType.ConnectionClosed; - } - - if (conI.ConstantID == PreviousSelected) - _selectedTreeNode = tNode; - } - else - { - tNode.ImageIndex = (int) TreeImageType.ConnectionClosed; - tNode.SelectedImageIndex = (int) TreeImageType.ConnectionClosed; - } - } - - private void AddContainerToList(TreeNode tNode) - { - var contI = new ContainerInfo - { - TreeNode = tNode, - Name = Convert.ToString(_sqlDataReader["Name"]) - }; - - var conI = GetConnectionInfoFromSql(); - conI.Parent = contI; - conI.IsContainer = true; - contI.CopyFrom(conI); - - if (DatabaseUpdate) - { - var prevCont = PreviousContainerList.FindByConstantID(conI.ConstantID); - if (prevCont != null) - contI.IsExpanded = prevCont.IsExpanded; - - if (conI.ConstantID == PreviousSelected) - _selectedTreeNode = tNode; - } - else - { - contI.IsExpanded = Convert.ToBoolean(_sqlDataReader["Expanded"]); - } - - ContainerList.Add(contI); - ConnectionList.Add(conI); - tNode.Tag = contI; - tNode.ImageIndex = (int)TreeImageType.Container; - tNode.SelectedImageIndex = (int)TreeImageType.Container; - } - - private ConnectionInfo GetConnectionInfoFromSql() - { - try - { - var connectionInfo = new ConnectionInfo - { - PositionID = Convert.ToInt32(_sqlDataReader["PositionID"]), - ConstantID = Convert.ToString(_sqlDataReader["ConstantID"]), - Name = Convert.ToString(_sqlDataReader["Name"]), - Description = Convert.ToString(_sqlDataReader["Description"]), - Hostname = Convert.ToString(_sqlDataReader["Hostname"]), - Username = Convert.ToString(_sqlDataReader["Username"]) - }; - - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - connectionInfo.Password = cryptographyProvider.Decrypt(Convert.ToString(_sqlDataReader["Password"]), _pW); - connectionInfo.Domain = Convert.ToString(_sqlDataReader["DomainName"]); - connectionInfo.DisplayWallpaper = Convert.ToBoolean(_sqlDataReader["DisplayWallpaper"]); - connectionInfo.DisplayThemes = Convert.ToBoolean(_sqlDataReader["DisplayThemes"]); - connectionInfo.CacheBitmaps = Convert.ToBoolean(_sqlDataReader["CacheBitmaps"]); - connectionInfo.UseConsoleSession = Convert.ToBoolean(_sqlDataReader["ConnectToConsole"]); - connectionInfo.RedirectDiskDrives = Convert.ToBoolean(_sqlDataReader["RedirectDiskDrives"]); - connectionInfo.RedirectPrinters = Convert.ToBoolean(_sqlDataReader["RedirectPrinters"]); - connectionInfo.RedirectPorts = Convert.ToBoolean(_sqlDataReader["RedirectPorts"]); - connectionInfo.RedirectSmartCards = Convert.ToBoolean(_sqlDataReader["RedirectSmartCards"]); - connectionInfo.RedirectKeys = Convert.ToBoolean(_sqlDataReader["RedirectKeys"]); - connectionInfo.RedirectSound = (ProtocolRDP.RDPSounds)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPSounds), Convert.ToString(_sqlDataReader["RedirectSound"])); - connectionInfo.Protocol = (ProtocolType)Tools.MiscTools.StringToEnum(typeof(ProtocolType), Convert.ToString(_sqlDataReader["Protocol"])); - connectionInfo.Port = Convert.ToInt32(_sqlDataReader["Port"]); - connectionInfo.PuttySession = Convert.ToString(_sqlDataReader["PuttySession"]); - connectionInfo.Colors = (ProtocolRDP.RDPColors)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPColors), Convert.ToString(_sqlDataReader["Colors"])); - connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDPResolutions), Convert.ToString(_sqlDataReader["Resolution"])); - connectionInfo.Icon = Convert.ToString(_sqlDataReader["Icon"]); - connectionInfo.Panel = Convert.ToString(_sqlDataReader["Panel"]); - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo) - { - CacheBitmaps = Convert.ToBoolean(_sqlDataReader["InheritCacheBitmaps"]), - Colors = Convert.ToBoolean(_sqlDataReader["InheritColors"]), - Description = Convert.ToBoolean(_sqlDataReader["InheritDescription"]), - DisplayThemes = Convert.ToBoolean(_sqlDataReader["InheritDisplayThemes"]), - DisplayWallpaper = Convert.ToBoolean(_sqlDataReader["InheritDisplayWallpaper"]), - Domain = Convert.ToBoolean(_sqlDataReader["InheritDomain"]), - Icon = Convert.ToBoolean(_sqlDataReader["InheritIcon"]), - Panel = Convert.ToBoolean(_sqlDataReader["InheritPanel"]), - Password = Convert.ToBoolean(_sqlDataReader["InheritPassword"]), - Port = Convert.ToBoolean(_sqlDataReader["InheritPort"]), - Protocol = Convert.ToBoolean(_sqlDataReader["InheritProtocol"]), - PuttySession = Convert.ToBoolean(_sqlDataReader["InheritPuttySession"]), - RedirectDiskDrives = Convert.ToBoolean(_sqlDataReader["InheritRedirectDiskDrives"]), - RedirectKeys = Convert.ToBoolean(_sqlDataReader["InheritRedirectKeys"]), - RedirectPorts = Convert.ToBoolean(_sqlDataReader["InheritRedirectPorts"]), - RedirectPrinters = Convert.ToBoolean(_sqlDataReader["InheritRedirectPrinters"]), - RedirectSmartCards = Convert.ToBoolean(_sqlDataReader["InheritRedirectSmartCards"]), - RedirectSound = Convert.ToBoolean(_sqlDataReader["InheritRedirectSound"]), - Resolution = Convert.ToBoolean(_sqlDataReader["InheritResolution"]), - UseConsoleSession = Convert.ToBoolean(_sqlDataReader["InheritUseConsoleSession"]), - Username = Convert.ToBoolean(_sqlDataReader["InheritUsername"]) - }; - - if (_confVersion > 1.5) //1.6 - { - connectionInfo.ICAEncryptionStrength = (ProtocolICA.EncryptionStrength)Tools.MiscTools.StringToEnum(typeof(ProtocolICA.EncryptionStrength), Convert.ToString(_sqlDataReader["ICAEncryptionStrength"])); - connectionInfo.Inheritance.ICAEncryptionStrength = Convert.ToBoolean(_sqlDataReader["InheritICAEncryptionStrength"]); - connectionInfo.PreExtApp = Convert.ToString(_sqlDataReader["PreExtApp"]); - connectionInfo.PostExtApp = Convert.ToString(_sqlDataReader["PostExtApp"]); - connectionInfo.Inheritance.PreExtApp = Convert.ToBoolean(_sqlDataReader["InheritPreExtApp"]); - connectionInfo.Inheritance.PostExtApp = Convert.ToBoolean(_sqlDataReader["InheritPostExtApp"]); - } - - if (_confVersion > 1.6) //1.7 - { - connectionInfo.VNCCompression = (ProtocolVNC.Compression)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.Compression), Convert.ToString(_sqlDataReader["VNCCompression"])); - connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.Encoding), Convert.ToString(_sqlDataReader["VNCEncoding"])); - connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.AuthMode), Convert.ToString(_sqlDataReader["VNCAuthMode"])); - connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.ProxyType), Convert.ToString(_sqlDataReader["VNCProxyType"])); - connectionInfo.VNCProxyIP = Convert.ToString(_sqlDataReader["VNCProxyIP"]); - connectionInfo.VNCProxyPort = Convert.ToInt32(_sqlDataReader["VNCProxyPort"]); - connectionInfo.VNCProxyUsername = Convert.ToString(_sqlDataReader["VNCProxyUsername"]); - connectionInfo.VNCProxyPassword = cryptographyProvider.Decrypt(Convert.ToString(_sqlDataReader["VNCProxyPassword"]), _pW); - connectionInfo.VNCColors = (ProtocolVNC.Colors)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.Colors), Convert.ToString(_sqlDataReader["VNCColors"])); - connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.SmartSizeMode), Convert.ToString(_sqlDataReader["VNCSmartSizeMode"])); - connectionInfo.VNCViewOnly = Convert.ToBoolean(_sqlDataReader["VNCViewOnly"]); - connectionInfo.Inheritance.VNCCompression = Convert.ToBoolean(_sqlDataReader["InheritVNCCompression"]); - connectionInfo.Inheritance.VNCEncoding = Convert.ToBoolean(_sqlDataReader["InheritVNCEncoding"]); - connectionInfo.Inheritance.VNCAuthMode = Convert.ToBoolean(_sqlDataReader["InheritVNCAuthMode"]); - connectionInfo.Inheritance.VNCProxyType = Convert.ToBoolean(_sqlDataReader["InheritVNCProxyType"]); - connectionInfo.Inheritance.VNCProxyIP = Convert.ToBoolean(_sqlDataReader["InheritVNCProxyIP"]); - connectionInfo.Inheritance.VNCProxyPort = Convert.ToBoolean(_sqlDataReader["InheritVNCProxyPort"]); - connectionInfo.Inheritance.VNCProxyUsername = Convert.ToBoolean(_sqlDataReader["InheritVNCProxyUsername"]); - connectionInfo.Inheritance.VNCProxyPassword = Convert.ToBoolean(_sqlDataReader["InheritVNCProxyPassword"]); - connectionInfo.Inheritance.VNCColors = Convert.ToBoolean(_sqlDataReader["InheritVNCColors"]); - connectionInfo.Inheritance.VNCSmartSizeMode = Convert.ToBoolean(_sqlDataReader["InheritVNCSmartSizeMode"]); - connectionInfo.Inheritance.VNCViewOnly = Convert.ToBoolean(_sqlDataReader["InheritVNCViewOnly"]); - } - - if (_confVersion > 1.7) //1.8 - { - connectionInfo.RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.AuthenticationLevel), Convert.ToString(_sqlDataReader["RDPAuthenticationLevel"])); - connectionInfo.Inheritance.RDPAuthenticationLevel = Convert.ToBoolean(_sqlDataReader["InheritRDPAuthenticationLevel"]); - } - - if (_confVersion > 1.8) //1.9 - { - connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Tools.MiscTools.StringToEnum(typeof(HTTPBase.RenderingEngine), Convert.ToString(_sqlDataReader["RenderingEngine"])); - connectionInfo.MacAddress = Convert.ToString(_sqlDataReader["MacAddress"]); - connectionInfo.Inheritance.RenderingEngine = Convert.ToBoolean(_sqlDataReader["InheritRenderingEngine"]); - connectionInfo.Inheritance.MacAddress = Convert.ToBoolean(_sqlDataReader["InheritMacAddress"]); - } - - if (_confVersion > 1.9) //2.0 - { - connectionInfo.UserField = Convert.ToString(_sqlDataReader["UserField"]); - connectionInfo.Inheritance.UserField = Convert.ToBoolean(_sqlDataReader["InheritUserField"]); - } - - if (_confVersion > 2.0) //2.1 - { - connectionInfo.ExtApp = Convert.ToString(_sqlDataReader["ExtApp"]); - connectionInfo.Inheritance.ExtApp = Convert.ToBoolean(_sqlDataReader["InheritExtApp"]); - } - - if (_confVersion >= 2.2) - { - connectionInfo.RDGatewayUsageMethod = (ProtocolRDP.RDGatewayUsageMethod)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDGatewayUsageMethod), Convert.ToString(_sqlDataReader["RDGatewayUsageMethod"])); - connectionInfo.RDGatewayHostname = Convert.ToString(_sqlDataReader["RDGatewayHostname"]); - connectionInfo.RDGatewayUseConnectionCredentials = (ProtocolRDP.RDGatewayUseConnectionCredentials)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDGatewayUseConnectionCredentials), Convert.ToString(_sqlDataReader["RDGatewayUseConnectionCredentials"])); - connectionInfo.RDGatewayUsername = Convert.ToString(_sqlDataReader["RDGatewayUsername"]); - connectionInfo.RDGatewayPassword = cryptographyProvider.Decrypt(Convert.ToString(_sqlDataReader["RDGatewayPassword"]), _pW); - connectionInfo.RDGatewayDomain = Convert.ToString(_sqlDataReader["RDGatewayDomain"]); - connectionInfo.Inheritance.RDGatewayUsageMethod = Convert.ToBoolean(_sqlDataReader["InheritRDGatewayUsageMethod"]); - connectionInfo.Inheritance.RDGatewayHostname = Convert.ToBoolean(_sqlDataReader["InheritRDGatewayHostname"]); - connectionInfo.Inheritance.RDGatewayUsername = Convert.ToBoolean(_sqlDataReader["InheritRDGatewayUsername"]); - connectionInfo.Inheritance.RDGatewayPassword = Convert.ToBoolean(_sqlDataReader["InheritRDGatewayPassword"]); - connectionInfo.Inheritance.RDGatewayDomain = Convert.ToBoolean(_sqlDataReader["InheritRDGatewayDomain"]); - } - - if (_confVersion >= 2.3) - { - connectionInfo.EnableFontSmoothing = Convert.ToBoolean(_sqlDataReader["EnableFontSmoothing"]); - connectionInfo.EnableDesktopComposition = Convert.ToBoolean(_sqlDataReader["EnableDesktopComposition"]); - connectionInfo.Inheritance.EnableFontSmoothing = Convert.ToBoolean(_sqlDataReader["InheritEnableFontSmoothing"]); - connectionInfo.Inheritance.EnableDesktopComposition = Convert.ToBoolean(_sqlDataReader["InheritEnableDesktopComposition"]); - } - - if (_confVersion >= 2.4) - { - connectionInfo.UseCredSsp = Convert.ToBoolean(_sqlDataReader["UseCredSsp"]); - connectionInfo.Inheritance.UseCredSsp = Convert.ToBoolean(_sqlDataReader["InheritUseCredSsp"]); - } - - if (_confVersion >= 2.5) - { - connectionInfo.LoadBalanceInfo = Convert.ToString(_sqlDataReader["LoadBalanceInfo"]); - connectionInfo.AutomaticResize = Convert.ToBoolean(_sqlDataReader["AutomaticResize"]); - connectionInfo.Inheritance.LoadBalanceInfo = Convert.ToBoolean(_sqlDataReader["InheritLoadBalanceInfo"]); - connectionInfo.Inheritance.AutomaticResize = Convert.ToBoolean(_sqlDataReader["InheritAutomaticResize"]); - } - - if (DatabaseUpdate) - connectionInfo.PleaseConnect = Convert.ToBoolean(_sqlDataReader["Connected"]); - - return connectionInfo; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strGetConnectionInfoFromSqlFailed + Environment.NewLine + ex.Message, true); - } - - return null; - } - - private delegate void SetSelectedNodeDelegate(TreeNode treeNode); - private static void SetSelectedNode(TreeNode treeNode) - { - if (ConnectionTree.TreeView != null && ConnectionTree.TreeView.InvokeRequired) - { - Windows.treeForm.Invoke(new SetSelectedNodeDelegate(SetSelectedNode), treeNode); - return; - } - Windows.treeForm.tvConnections.SelectedNode = treeNode; - } - - private bool Authenticate(string value, bool compareToOriginalValue, RootNodeInfo rootInfo = null) - { - var passwordName = ""; - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - passwordName = Language.strSQLServer.TrimEnd(':'); - - - if (compareToOriginalValue) - { - while (cryptographyProvider.Decrypt(value, _pW) == value) - { - _pW = Tools.MiscTools.PasswordDialog(passwordName, false); - if (_pW.Length == 0) - return false; - } - } - else - { - while (cryptographyProvider.Decrypt(value, _pW) != "ThisIsProtected") - { - _pW = Tools.MiscTools.PasswordDialog(passwordName, false); - if (_pW.Length == 0) - return false; - } - - if (rootInfo == null) return true; - rootInfo.Password = true; - rootInfo.PasswordString = _pW.ConvertToUnsecureString(); - } - - return true; - } - - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SqlConnectionsUpdateChecker.cs b/mRemoteV1/Config/Connections/SqlConnectionsUpdateChecker.cs deleted file mode 100644 index b81ef2a31..000000000 --- a/mRemoteV1/Config/Connections/SqlConnectionsUpdateChecker.cs +++ /dev/null @@ -1,131 +0,0 @@ -using mRemoteNG.App; -using mRemoteNG.Messages; -using System; -using System.Data; -using System.Data.SqlClient; -using System.Threading; - -namespace mRemoteNG.Config.Connections -{ - public class SqlConnectionsUpdateChecker : IDisposable - { - private SqlConnector sqlConnector; - private SqlCommand sqlQuery; - private SqlDataReader sqlReader; - - - public SqlConnectionsUpdateChecker() - { - sqlConnector = default(SqlConnectorImp); - sqlQuery = default(SqlCommand); - sqlReader = default(SqlDataReader); - } - - ~SqlConnectionsUpdateChecker() - { - Dispose(false); - } - - - public void IsDatabaseUpdateAvailableAsync() - { - Thread t = new Thread(IsDatabaseUpdateAvailableDelegate); - t.SetApartmentState(ApartmentState.STA); - t.Start(); - } - - private void IsDatabaseUpdateAvailableDelegate() - { - IsDatabaseUpdateAvailable(); - } - - public bool IsDatabaseUpdateAvailable() - { - ConnectToSqlDB(); - BuildSqlQueryToGetUpdateStatus(); - ExecuteQuery(); - bool updateIsAvailable = DatabaseIsMoreUpToDateThanUs(); - SendUpdateCheckFinishedEvent(updateIsAvailable); - return updateIsAvailable; - } - private void ConnectToSqlDB() - { - try - { - sqlConnector = new SqlConnectorImp(); - sqlConnector.Connect(); - } - catch(Exception e) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Unable to connect to Sql DB to check for updates." + Environment.NewLine + e.Message, true); - } - } - private void BuildSqlQueryToGetUpdateStatus() - { - try - { - SqlCommandBuilder sqlCmdBuilder = new SqlUpdateQueryBuilder(); - sqlQuery = sqlCmdBuilder.BuildCommand(); - sqlConnector.AssociateItemToThisConnector(sqlQuery); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Could not build query to check for updates from the Sql server." + Environment.NewLine + ex.Message, true); - } - } - private void ExecuteQuery() - { - try - { - sqlReader = sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); - sqlReader.Read(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Error executing Sql query to get updates from the DB." + Environment.NewLine + ex.Message, true); - } - } - private bool DatabaseIsMoreUpToDateThanUs() - { - if (GetLastUpdateTimeFromDBResponse() > Runtime.LastSqlUpdate) - return true; - return false; - } - private DateTime GetLastUpdateTimeFromDBResponse() - { - DateTime LastUpdateInDB = default(DateTime); - if (sqlReader.HasRows) - LastUpdateInDB = Convert.ToDateTime(sqlReader["LastUpdate"]); - return LastUpdateInDB; - } - private void SendUpdateCheckFinishedEvent(bool UpdateAvailable) - { - if (SQLUpdateCheckFinishedEvent != null) - SQLUpdateCheckFinishedEvent(UpdateAvailable); - } - - - public void Dispose() - { - Dispose(true); - } - - private void Dispose(bool itIsSafeToDisposeManagedObjects) - { - if (itIsSafeToDisposeManagedObjects) - { - sqlConnector.Disconnect(); - sqlConnector.Dispose(); - } - } - - - public delegate void SQLUpdateCheckFinishedEventHandler(bool UpdateAvailable); - private static SQLUpdateCheckFinishedEventHandler SQLUpdateCheckFinishedEvent; - public static event SQLUpdateCheckFinishedEventHandler SQLUpdateCheckFinished - { - add { SQLUpdateCheckFinishedEvent = (SQLUpdateCheckFinishedEventHandler)System.Delegate.Combine(SQLUpdateCheckFinishedEvent, value); } - remove { SQLUpdateCheckFinishedEvent = (SQLUpdateCheckFinishedEventHandler)System.Delegate.Remove(SQLUpdateCheckFinishedEvent, value); } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SqlUpdateQueryBuilder.cs b/mRemoteV1/Config/Connections/SqlUpdateQueryBuilder.cs deleted file mode 100644 index 0c5b2c286..000000000 --- a/mRemoteV1/Config/Connections/SqlUpdateQueryBuilder.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Data.SqlClient; - -namespace mRemoteNG.Config.Connections -{ - public class SqlUpdateQueryBuilder : SqlCommandBuilder - { - private string _updateQuery; - - public SqlUpdateQueryBuilder() - { - Initialize(); - } - - private void Initialize() - { - _updateQuery = "SELECT * FROM tblUpdate"; - } - - public SqlCommand BuildCommand() - { - return new SqlCommand(_updateQuery); - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/SqlUpdateTimer.cs b/mRemoteV1/Config/Connections/SqlUpdateTimer.cs deleted file mode 100644 index 2e7f079f9..000000000 --- a/mRemoteV1/Config/Connections/SqlUpdateTimer.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Timers; -using mRemoteNG.App; - -namespace mRemoteNG.Config.Connections -{ - public class SqlUpdateTimer : IDisposable - { - private Timer _sqlUpdateTimer; - - public SqlUpdateTimer() - { - Initialize(); - } - - ~SqlUpdateTimer() - { - Dispose(false); - } - - private void Initialize() - { - _sqlUpdateTimer = new Timer(); - _sqlUpdateTimer.Interval = 3000; - _sqlUpdateTimer.Elapsed += sqlUpdateTimer_Elapsed; - } - - public void Enable() - { - _sqlUpdateTimer.Start(); - } - - public void Disable() - { - _sqlUpdateTimer.Stop(); - } - - public bool IsUpdateCheckingEnabled() - { - return _sqlUpdateTimer.Enabled; - } - - private static void sqlUpdateTimer_Elapsed(object sender, ElapsedEventArgs e) - { - SqlUpdateTimerElapsedEvent(); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - protected void Dispose(bool itIsSafeToAlsoFreeManagedObjects) - { - if (itIsSafeToAlsoFreeManagedObjects) - { - StopTimer(); - } - } - private void StopTimer() - { - try - { - _sqlUpdateTimer.Stop(); - _sqlUpdateTimer.Close(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("SqlUpdateTimer StopTimer Exception", ex); - } - } - - - public delegate void SqlUpdateTimerElapsedEventHandler(); - private static SqlUpdateTimerElapsedEventHandler SqlUpdateTimerElapsedEvent; - public static event SqlUpdateTimerElapsedEventHandler SqlUpdateTimerElapsed - { - add { SqlUpdateTimerElapsedEvent = (SqlUpdateTimerElapsedEventHandler)Delegate.Combine(SqlUpdateTimerElapsedEvent, value); } - remove { SqlUpdateTimerElapsedEvent = (SqlUpdateTimerElapsedEventHandler)Delegate.Remove(SqlUpdateTimerElapsedEvent, value); } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/DataProviders/FileDataProvider.cs b/mRemoteV1/Config/DataProviders/FileDataProvider.cs new file mode 100644 index 000000000..8d5431e63 --- /dev/null +++ b/mRemoteV1/Config/DataProviders/FileDataProvider.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using mRemoteNG.App; + +namespace mRemoteNG.Config.DataProviders +{ + public class FileDataProvider : IDataProvider + { + public string FilePath { get; set; } + + public FileDataProvider(string filePath) + { + FilePath = filePath; + } + + public virtual string Load() + { + var fileContents = ""; + try + { + fileContents = File.ReadAllText(FilePath); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Failed to load file {FilePath}", ex); + } + return fileContents; + } + + public virtual void Save(string content) + { + try + { + File.WriteAllText(FilePath, content); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Failed to save file {FilePath}", ex); + } + } + + public virtual void MoveTo(string newPath) + { + try + { + File.Move(FilePath, newPath); + FilePath = newPath; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Failed to move file {FilePath} to {newPath}", ex); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/DataProviders/FileDataProviderWithBackup.cs b/mRemoteV1/Config/DataProviders/FileDataProviderWithBackup.cs new file mode 100644 index 000000000..d04bf5b3a --- /dev/null +++ b/mRemoteV1/Config/DataProviders/FileDataProviderWithBackup.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using mRemoteNG.App; + +namespace mRemoteNG.Config.DataProviders +{ + public class FileDataProviderWithBackup : FileDataProvider + { + protected string BackupFileSuffix = ".backup"; + + public FileDataProviderWithBackup(string filePath) : base(filePath) + { + } + + public override void Save(string content) + { + CreateBackup(); + base.Save(content); + } + + protected virtual void CreateBackup() + { + var backupFileName = FilePath + BackupFileSuffix; + try + { + File.Copy(FilePath, backupFileName, true); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Failed to create backup of file {FilePath}", ex); + throw; + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/DataProviders/FileDataProviderWithRollingBackup.cs b/mRemoteV1/Config/DataProviders/FileDataProviderWithRollingBackup.cs new file mode 100644 index 000000000..9d01d64b7 --- /dev/null +++ b/mRemoteV1/Config/DataProviders/FileDataProviderWithRollingBackup.cs @@ -0,0 +1,34 @@ +using System; +using mRemoteNG.App; + +namespace mRemoteNG.Config.DataProviders +{ + public class FileDataProviderWithRollingBackup : FileDataProviderWithBackup + { + public FileDataProviderWithRollingBackup(string filePath) : base(filePath) + { + } + + protected override void CreateBackup() + { + CreateRollingBackup(); + base.CreateBackup(); + } + + protected virtual void CreateRollingBackup() + { + var timeStamp = $"{DateTime.Now:yyyyMMdd-HHmmss-ffff}"; + var normalBackup = new FileDataProviderWithBackup(FilePath + BackupFileSuffix); + var normalBackupWithoutSuffix = normalBackup.FilePath.Replace(BackupFileSuffix, ""); + try + { + normalBackup.MoveTo(normalBackupWithoutSuffix + timeStamp + BackupFileSuffix); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace($"Failed to create rolling backup of file {FilePath}", ex); + throw; + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/DataProviders/IDataProvider.cs b/mRemoteV1/Config/DataProviders/IDataProvider.cs new file mode 100644 index 000000000..1f665f17a --- /dev/null +++ b/mRemoteV1/Config/DataProviders/IDataProvider.cs @@ -0,0 +1,10 @@ + +namespace mRemoteNG.Config.DataProviders +{ + public interface IDataProvider + { + TFormat Load(); + + void Save(TFormat contents); + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/DataProviders/SqlDataProvider.cs b/mRemoteV1/Config/DataProviders/SqlDataProvider.cs new file mode 100644 index 000000000..2b91c955d --- /dev/null +++ b/mRemoteV1/Config/DataProviders/SqlDataProvider.cs @@ -0,0 +1,56 @@ +using System.Data; +using System.Data.SqlClient; +using mRemoteNG.Config.DatabaseConnectors; + + +namespace mRemoteNG.Config.DataProviders +{ + public class SqlDataProvider : IDataProvider + { + public SqlDatabaseConnector SqlDatabaseConnector { get; } + + public SqlDataProvider(SqlDatabaseConnector sqlDatabaseConnector) + { + SqlDatabaseConnector = sqlDatabaseConnector; + } + + ~SqlDataProvider() + { + SqlDatabaseConnector.Dispose(); + } + + public DataTable Load() + { + var dataTable = new DataTable(); + var sqlQuery = new SqlCommand("SELECT * FROM tblCons ORDER BY PositionID ASC"); + SqlDatabaseConnector.AssociateItemToThisConnector(sqlQuery); + if (!SqlDatabaseConnector.IsConnected) + OpenConnection(); + var sqlDataReader = sqlQuery.ExecuteReader(CommandBehavior.CloseConnection); + + if (sqlDataReader.HasRows) + dataTable.Load(sqlDataReader); + sqlDataReader.Close(); + return dataTable; + } + + public void Save(DataTable dataTable) + { + if (!SqlDatabaseConnector.IsConnected) + OpenConnection(); + var sqlBulkCopy = new SqlBulkCopy(SqlDatabaseConnector.SqlConnection) {DestinationTableName = "dbo.tblCons"}; + sqlBulkCopy.WriteToServer(dataTable); + sqlBulkCopy.Close(); + } + + public void OpenConnection() + { + SqlDatabaseConnector.Connect(); + } + + public void CloseConnection() + { + SqlDatabaseConnector.Disconnect(); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/SqlConnector.cs b/mRemoteV1/Config/DatabaseConnectors/IDatabaseConnector.cs similarity index 56% rename from mRemoteV1/Config/SqlConnector.cs rename to mRemoteV1/Config/DatabaseConnectors/IDatabaseConnector.cs index 4ec8faaf9..c1f52a537 100644 --- a/mRemoteV1/Config/SqlConnector.cs +++ b/mRemoteV1/Config/DatabaseConnectors/IDatabaseConnector.cs @@ -1,9 +1,11 @@ using System; using System.Data.SqlClient; -namespace mRemoteNG.Config + +namespace mRemoteNG.Config.DatabaseConnectors { - public interface SqlConnector : IDisposable + public interface IDatabaseConnector : IDisposable { + bool IsConnected { get; } void Connect(); void Disconnect(); void AssociateItemToThisConnector(SqlCommand sqlCommand); diff --git a/mRemoteV1/Config/SqlConnectorImp.cs b/mRemoteV1/Config/DatabaseConnectors/SqlDatabaseConnector.cs similarity index 65% rename from mRemoteV1/Config/SqlConnectorImp.cs rename to mRemoteV1/Config/DatabaseConnectors/SqlDatabaseConnector.cs index 387e5bc28..ba13a1967 100644 --- a/mRemoteV1/Config/SqlConnectorImp.cs +++ b/mRemoteV1/Config/DatabaseConnectors/SqlDatabaseConnector.cs @@ -1,24 +1,27 @@ -using mRemoteNG.App.Info; +using System.Data; using System.Data.SqlClient; +using mRemoteNG.App.Info; using mRemoteNG.Security.SymmetricEncryption; -namespace mRemoteNG.Config +namespace mRemoteNG.Config.DatabaseConnectors { - public class SqlConnectorImp : SqlConnector + public class SqlDatabaseConnector : IDatabaseConnector { - private SqlConnection _sqlConnection = default(SqlConnection); + public SqlConnection SqlConnection { get; private set; } = default(SqlConnection); private string _sqlConnectionString = ""; private string _sqlHost; private string _sqlCatalog; private string _sqlUsername; private string _sqlPassword; - public SqlConnectorImp() + public bool IsConnected => (SqlConnection.State == ConnectionState.Open); + + public SqlDatabaseConnector() { Initialize(); } - ~SqlConnectorImp() + ~SqlDatabaseConnector() { Dispose(false); } @@ -26,7 +29,7 @@ namespace mRemoteNG.Config private void Initialize() { BuildSqlConnectionString(); - _sqlConnection = new SqlConnection(_sqlConnectionString); + SqlConnection = new SqlConnection(_sqlConnectionString); } private void BuildSqlConnectionString() @@ -41,12 +44,12 @@ namespace mRemoteNG.Config private void BuildSqlConnectionStringWithCustomCredentials() { - _sqlConnectionString = string.Format("Data Source={0};Initial Catalog={1};User Id={2};Password={3}", _sqlHost, _sqlCatalog, _sqlUsername, _sqlPassword); + _sqlConnectionString = $"Data Source={_sqlHost};Initial Catalog={_sqlCatalog};User Id={_sqlUsername};Password={_sqlPassword}"; } private void BuildSqlConnectionStringWithDefaultCredentials() { - _sqlConnectionString = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=True", _sqlHost, _sqlCatalog); + _sqlConnectionString = $"Data Source={_sqlHost};Initial Catalog={_sqlCatalog};Integrated Security=True"; } private void GetSqlConnectionDataFromSettings() @@ -60,19 +63,18 @@ namespace mRemoteNG.Config public void Connect() { - _sqlConnection.Open(); + SqlConnection.Open(); } public void Disconnect() { - _sqlConnection.Close(); + SqlConnection.Close(); } public void AssociateItemToThisConnector(SqlCommand sqlCommand) { - sqlCommand.Connection = _sqlConnection; + sqlCommand.Connection = SqlConnection; } - public void Dispose() { @@ -80,11 +82,9 @@ namespace mRemoteNG.Config } private void Dispose(bool itIsSafeToFreeManagedObjects) { - if (itIsSafeToFreeManagedObjects) - { - _sqlConnection.Close(); - _sqlConnection.Dispose(); - } + if (!itIsSafeToFreeManagedObjects) return; + SqlConnection.Close(); + SqlConnection.Dispose(); } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Import/ActiveDirectory.cs b/mRemoteV1/Config/Import/ActiveDirectory.cs deleted file mode 100644 index 045da331b..000000000 --- a/mRemoteV1/Config/Import/ActiveDirectory.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Windows.Forms; -using System.DirectoryServices; -using mRemoteNG.App; -using System.Text.RegularExpressions; -using mRemoteNG.Connection; -using mRemoteNG.Container; -using mRemoteNG.Tree; - -namespace mRemoteNG.Config.Import -{ - public class ActiveDirectory - { - public static void Import(string ldapPath, TreeNode parentTreeNode) - { - try - { - var treeNode = ConnectionTreeNode.AddNode(TreeNodeType.Container); - - var containerInfo = new ContainerInfo(); - containerInfo.TreeNode = treeNode; - - var name = ""; - var match = Regex.Match(ldapPath, "ou=([^,]*)", RegexOptions.IgnoreCase); - if (match.Success) - { - name = match.Groups[1].Captures[0].Value; - } - else - { - name = Language.strActiveDirectory; - } - - containerInfo.Name = name; - - // We can only inherit from a container node, not the root node or connection nodes - if (ConnectionTreeNode.GetNodeType(parentTreeNode) == TreeNodeType.Container) - { - containerInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - } - else - { - containerInfo.Inheritance.DisableInheritance(); - } - - treeNode.Text = name; - treeNode.Name = name; - treeNode.Tag = containerInfo; - Runtime.ContainerList.Add(containerInfo); - - ImportComputers(ldapPath, treeNode); - - parentTreeNode.Nodes.Add(treeNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage("Config.Import.ActiveDirectory.Import() failed.", ex, logOnly: true); - } - } - - private static void ImportComputers(string ldapPath, TreeNode parentTreeNode) - { - try - { - const string ldapFilter = "(objectClass=computer)"; - - var ldapSearcher = new DirectorySearcher(); - var ldapResults = default(SearchResultCollection); - var ldapResult = default(SearchResult); - - ldapSearcher.SearchRoot = new DirectoryEntry(ldapPath); - ldapSearcher.PropertiesToLoad.AddRange(new[] {"securityEquals", "cn"}); - ldapSearcher.Filter = ldapFilter; - ldapSearcher.SearchScope = SearchScope.OneLevel; - - ldapResults = ldapSearcher.FindAll(); - - foreach (SearchResult tempLoopVar_ldapResult in ldapResults) - { - ldapResult = tempLoopVar_ldapResult; - var with_2 = ldapResult.GetDirectoryEntry(); - var displayName = Convert.ToString(with_2.Properties["cn"].Value); - var description = Convert.ToString(with_2.Properties["Description"].Value); - var hostName = Convert.ToString(with_2.Properties["dNSHostName"].Value); - - var treeNode = ConnectionTreeNode.AddNode(TreeNodeType.Connection, displayName); - - var connectionInfo = new ConnectionInfo(); - var inheritanceInfo = new ConnectionInfoInheritance(connectionInfo); - inheritanceInfo.TurnOnInheritanceCompletely(); - inheritanceInfo.Description = false; - if (parentTreeNode.Tag is ContainerInfo) - { - connectionInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - } - connectionInfo.Inheritance = inheritanceInfo; - connectionInfo.Name = displayName; - connectionInfo.Hostname = hostName; - connectionInfo.Description = description; - connectionInfo.TreeNode = treeNode; - treeNode.Name = displayName; - treeNode.Tag = connectionInfo; //set the nodes tag to the conI - //add connection to connections - Runtime.ConnectionList.Add(connectionInfo); - - parentTreeNode.Nodes.Add(treeNode); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage("Config.Import.ActiveDirectory.ImportComputers() failed.", ex, logOnly: true); - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/ActiveDirectoryImporter.cs b/mRemoteV1/Config/Import/ActiveDirectoryImporter.cs new file mode 100644 index 000000000..39be73d71 --- /dev/null +++ b/mRemoteV1/Config/Import/ActiveDirectoryImporter.cs @@ -0,0 +1,36 @@ +using System; +using System.Linq; +using mRemoteNG.App; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Container; + + +namespace mRemoteNG.Config.Import +{ + public class ActiveDirectoryImporter : IConnectionImporter + { + public void Import(object ldapPath, ContainerInfo destinationContainer) + { + var ldapPathAsString = ldapPath as string; + if (ldapPathAsString == null) return; + Import(ldapPathAsString, destinationContainer); + } + + public void Import(string ldapPath, ContainerInfo destinationContainer) + { + try + { + var deserializer = new ActiveDirectoryDeserializer(ldapPath); + var connectionTreeModel = deserializer.Deserialize(); + var importedRootNode = connectionTreeModel.RootNodes.First(); + if (importedRootNode == null) return; + var childrenToAdd = importedRootNode.Children.ToArray(); + destinationContainer.AddChildRange(childrenToAdd); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage("Config.Import.ActiveDirectory.Import() failed.", ex, logOnly: true); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/IConnectionImporter.cs b/mRemoteV1/Config/Import/IConnectionImporter.cs new file mode 100644 index 000000000..f09f9ae99 --- /dev/null +++ b/mRemoteV1/Config/Import/IConnectionImporter.cs @@ -0,0 +1,10 @@ +using mRemoteNG.Container; + + +namespace mRemoteNG.Config.Import +{ + public interface IConnectionImporter + { + void Import(object source, ContainerInfo destinationContainer); + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/PortScan.cs b/mRemoteV1/Config/Import/PortScan.cs deleted file mode 100644 index 90374531a..000000000 --- a/mRemoteV1/Config/Import/PortScan.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Collections; -using System.Windows.Forms; -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Connection.Protocol; -using mRemoteNG.Container; -using mRemoteNG.Tools; - - -namespace mRemoteNG.Config.Import -{ - public static class PortScan - { - public static void Import(IEnumerable hosts, ProtocolType protocol, TreeNode parentTreeNode) - { - foreach (ScanHost host in hosts) - { - var finalProtocol = default(ProtocolType); - var protocolValid = false; - - var treeNode = Tree.ConnectionTreeNode.AddNode(Tree.TreeNodeType.Connection, host.HostNameWithoutDomain); - - var connectionInfo = new ConnectionInfo(); - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo); - - connectionInfo.Name = host.HostNameWithoutDomain; - connectionInfo.Hostname = host.HostName; - - switch (protocol) - { - case ProtocolType.SSH2: - if (host.SSH) - { - finalProtocol = ProtocolType.SSH2; - protocolValid = true; - } - break; - case ProtocolType.Telnet: - if (host.Telnet) - { - finalProtocol = ProtocolType.Telnet; - protocolValid = true; - } - break; - case ProtocolType.HTTP: - if (host.HTTP) - { - finalProtocol = ProtocolType.HTTP; - protocolValid = true; - } - break; - case ProtocolType.HTTPS: - if (host.HTTPS) - { - finalProtocol = ProtocolType.HTTPS; - protocolValid = true; - } - break; - case ProtocolType.Rlogin: - if (host.Rlogin) - { - finalProtocol = ProtocolType.Rlogin; - protocolValid = true; - } - break; - case ProtocolType.RDP: - if (host.RDP) - { - finalProtocol = ProtocolType.RDP; - protocolValid = true; - } - break; - case ProtocolType.VNC: - if (host.VNC) - { - finalProtocol = ProtocolType.VNC; - protocolValid = true; - } - break; - } - - if (protocolValid) - { - connectionInfo.Protocol = finalProtocol; - connectionInfo.SetDefaultPort(); - - treeNode.Tag = connectionInfo; - parentTreeNode.Nodes.Add(treeNode); - - if (parentTreeNode.Tag is ContainerInfo) - { - connectionInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - } - - Runtime.ConnectionList.Add(connectionInfo); - } - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/PortScanImporter.cs b/mRemoteV1/Config/Import/PortScanImporter.cs new file mode 100644 index 000000000..dcd8a960f --- /dev/null +++ b/mRemoteV1/Config/Import/PortScanImporter.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNG.Tools; + + +namespace mRemoteNG.Config.Import +{ + public class PortScanImporter : IConnectionImporter + { + private readonly ProtocolType _targetProtocolType; + + public PortScanImporter(ProtocolType targetProtocolType) + { + _targetProtocolType = targetProtocolType; + } + + public void Import(object hosts, ContainerInfo destinationContainer) + { + var hostsAsEnumerableScanHost = hosts as IEnumerable; + if (hostsAsEnumerableScanHost == null) return; + Import(hostsAsEnumerableScanHost, destinationContainer); + } + + public void Import(IEnumerable hosts, ContainerInfo destinationContainer) + { + var deserializer = new PortScanDeserializer(hosts, _targetProtocolType); + var connectionTreeModel = deserializer.Deserialize(); + + var importedRootNode = connectionTreeModel.RootNodes.First(); + if (importedRootNode == null) return; + var childrenToAdd = importedRootNode.Children.ToArray(); + destinationContainer.AddChildRange(childrenToAdd); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/PuttyConnectionManager.cs b/mRemoteV1/Config/Import/PuttyConnectionManager.cs deleted file mode 100644 index da66322a0..000000000 --- a/mRemoteV1/Config/Import/PuttyConnectionManager.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Windows.Forms; -using System.Xml; -using System.IO; -using mRemoteNG.App; -using mRemoteNG.Connection.Protocol; -using mRemoteNG.Connection; -using mRemoteNG.Tree; -using mRemoteNG.Container; - -namespace mRemoteNG.Config.Import -{ - public class PuttyConnectionManager - { - public static void Import(string fileName, TreeNode parentTreeNode) - { - XmlDocument xmlDocument = new XmlDocument(); - xmlDocument.Load(fileName); - - XmlNode configurationNode = xmlDocument.SelectSingleNode("/configuration"); - //Dim version As New Version(configurationNode.Attributes("version").Value) - //If Not version = New Version(0, 7, 1, 136) Then - // Throw New FileFormatException(String.Format("Unsupported file version ({0}).", version)) - //End If - - foreach (XmlNode rootNode in configurationNode.SelectNodes("./root")) - { - ImportRootOrContainer(rootNode, parentTreeNode); - } - } - - private static void ImportRootOrContainer(XmlNode xmlNode, TreeNode parentTreeNode) - { - string xmlNodeType = xmlNode.Attributes["type"].Value; - switch (xmlNode.Name) - { - case "root": - if (!(string.Compare(xmlNodeType, "database", ignoreCase: true) == 0)) - { - throw (new FileFormatException(string.Format("Unrecognized root node type ({0}).", xmlNodeType))); - } - break; - case "container": - if (!(string.Compare(xmlNodeType, "folder", ignoreCase: true) == 0)) - { - throw (new FileFormatException(string.Format("Unrecognized root node type ({0}).", xmlNodeType))); - } - break; - default: - // ReSharper disable once LocalizableElement - throw (new ArgumentException("Argument must be either a root or a container node.", "xmlNode")); - } - - if (parentTreeNode == null) - { - throw (new InvalidOperationException("parentInfo.TreeNode must not be null.")); - } - - string name = xmlNode.Attributes["name"].Value; - - TreeNode treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); - - ContainerInfo containerInfo = new ContainerInfo(); - containerInfo.TreeNode = treeNode; - containerInfo.Name = name; - - ConnectionInfo connectionInfo = CreateConnectionInfo(name); - connectionInfo.Parent = containerInfo; - connectionInfo.IsContainer = true; - containerInfo.CopyFrom(connectionInfo); - - // We can only inherit from a container node, not the root node or connection nodes - if (ConnectionTreeNode.GetNodeType(parentTreeNode) == TreeNodeType.Container) - { - containerInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - } - else - { - connectionInfo.Inheritance.DisableInheritance(); - } - - treeNode.Name = name; - treeNode.Tag = containerInfo; - treeNode.ImageIndex = (int)TreeImageType.Container; - treeNode.SelectedImageIndex = (int)TreeImageType.Container; - - foreach (XmlNode childNode in xmlNode.SelectNodes("./*")) - { - switch (childNode.Name) - { - case "container": - ImportRootOrContainer(childNode, treeNode); - break; - case "connection": - ImportConnection(childNode, treeNode); - break; - default: - throw (new FileFormatException(string.Format("Unrecognized child node ({0}).", childNode.Name))); - } - } - - containerInfo.IsExpanded = bool.Parse(xmlNode.Attributes["expanded"].InnerText); - if (containerInfo.IsExpanded) - { - treeNode.Expand(); - } - - Runtime.ContainerList.Add(containerInfo); - } - - private static void ImportConnection(XmlNode connectionNode, TreeNode parentTreeNode) - { - string connectionNodeType = connectionNode.Attributes["type"].Value; - if (!(string.Compare(connectionNodeType, "PuTTY", ignoreCase: true) == 0)) - { - throw (new FileFormatException(string.Format("Unrecognized connection node type ({0}).", connectionNodeType))); - } - - string name = connectionNode.Attributes["name"].Value; - TreeNode treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); - - ConnectionInfo connectionInfo = ConnectionInfoFromXml(connectionNode); - connectionInfo.TreeNode = treeNode; - connectionInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - - treeNode.Name = name; - treeNode.Tag = connectionInfo; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - - Runtime.ConnectionList.Add(connectionInfo); - } - - private static ConnectionInfo CreateConnectionInfo(string name) - { - ConnectionInfo connectionInfo = new ConnectionInfo(); - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo); - connectionInfo.Name = name; - return connectionInfo; - } - - private static ConnectionInfo ConnectionInfoFromXml(XmlNode xmlNode) - { - XmlNode connectionInfoNode = xmlNode.SelectSingleNode("./connection_info"); - - string name = connectionInfoNode.SelectSingleNode("./name").InnerText; - ConnectionInfo connectionInfo = CreateConnectionInfo(name); - - string protocol = connectionInfoNode.SelectSingleNode("./protocol").InnerText; - switch (protocol.ToLowerInvariant()) - { - case "telnet": - connectionInfo.Protocol = ProtocolType.Telnet; - break; - case "ssh": - connectionInfo.Protocol = ProtocolType.SSH2; - break; - default: - throw (new FileFormatException(string.Format("Unrecognized protocol ({0}).", protocol))); - } - - connectionInfo.Hostname = connectionInfoNode.SelectSingleNode("./host").InnerText; - connectionInfo.Port = Convert.ToInt32(connectionInfoNode.SelectSingleNode("./port").InnerText); - connectionInfo.PuttySession = connectionInfoNode.SelectSingleNode("./session").InnerText; - // ./commandline - connectionInfo.Description = connectionInfoNode.SelectSingleNode("./description").InnerText; - - XmlNode loginNode = xmlNode.SelectSingleNode("./login"); - connectionInfo.Username = loginNode.SelectSingleNode("login").InnerText; - connectionInfo.Password = loginNode.SelectSingleNode("password").InnerText; - // ./prompt - - // ./timeout/connectiontimeout - // ./timeout/logintimeout - // ./timeout/passwordtimeout - // ./timeout/commandtimeout - - // ./command/command1 - // ./command/command2 - // ./command/command3 - // ./command/command4 - // ./command/command5 - - // ./options/loginmacro - // ./options/postcommands - // ./options/endlinechar - - return connectionInfo; - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/PuttyConnectionManagerImporter.cs b/mRemoteV1/Config/Import/PuttyConnectionManagerImporter.cs new file mode 100644 index 000000000..5da1b343a --- /dev/null +++ b/mRemoteV1/Config/Import/PuttyConnectionManagerImporter.cs @@ -0,0 +1,35 @@ +using System.IO; +using System.Linq; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Container; + + +namespace mRemoteNG.Config.Import +{ + public class PuttyConnectionManagerImporter : IConnectionImporter + { + public void Import(object filePath, ContainerInfo destinationContainer) + { + var filePathAsString = filePath as string; + if (filePathAsString == null) + return; + if (File.Exists(filePathAsString)) + Import(filePathAsString, destinationContainer); + } + + public void Import(string filePath, ContainerInfo destinationContainer) + { + var dataProvider = new FileDataProvider(filePath); + var xmlContent = dataProvider.Load(); + + var deserializer = new PuttyConnectionManagerDeserializer(xmlContent); + var connectionTreeModel = deserializer.Deserialize(); + + var importedRootNode = connectionTreeModel.RootNodes.First(); + if (importedRootNode == null) return; + var childrenToAdd = importedRootNode.Children.ToArray(); + destinationContainer.AddChildRange(childrenToAdd); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/RemoteDesktopConnection.cs b/mRemoteV1/Config/Import/RemoteDesktopConnection.cs deleted file mode 100644 index 4f873d8b4..000000000 --- a/mRemoteV1/Config/Import/RemoteDesktopConnection.cs +++ /dev/null @@ -1,221 +0,0 @@ -using System; -using System.Windows.Forms; -using System.IO; -using mRemoteNG.App; -using mRemoteNG.Connection.Protocol.RDP; -using mRemoteNG.Container; -using mRemoteNG.Connection; -using mRemoteNG.Tree; - -namespace mRemoteNG.Config.Import -{ - public class RemoteDesktopConnection - { - public static void Import(string fileName, TreeNode parentTreeNode) - { - string[] lines = File.ReadAllLines(fileName); - - string name = Path.GetFileNameWithoutExtension(fileName); - TreeNode treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); - - ConnectionInfo connectionInfo = new ConnectionInfo(); - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo); - connectionInfo.Name = name; - connectionInfo.TreeNode = treeNode; - - if (treeNode.Parent.Tag is ContainerInfo) - { - connectionInfo.Parent = (ContainerInfo)treeNode.Parent.Tag; - } - - treeNode.Name = name; - treeNode.Tag = connectionInfo; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - - foreach (string line in lines) - { - string[] parts = line.Split(new char[] {':'}, 3); - if (parts.Length < 3) - { - continue; - } - - string key = parts[0]; - string value = parts[2]; - - SetConnectionInfoParameter(connectionInfo, key, value); - } - - Runtime.ConnectionList.Add(connectionInfo); - } - - private static void SetConnectionInfoParameter(ConnectionInfo connectionInfo, string key, string value) - { - switch (key.ToLower()) - { - case "full address": - Uri uri = new Uri("dummyscheme" + Uri.SchemeDelimiter + value); - if (!string.IsNullOrEmpty(uri.Host)) - { - connectionInfo.Hostname = uri.Host; - } - if (!(uri.Port == -1)) - { - connectionInfo.Port = uri.Port; - } - break; - case "server port": - connectionInfo.Port = Convert.ToInt32(value); - break; - case "username": - connectionInfo.Username = value; - break; - case "domain": - connectionInfo.Domain = value; - break; - case "session bpp": - switch (value) - { - case "8": - connectionInfo.Colors = ProtocolRDP.RDPColors.Colors256; - break; - case "15": - connectionInfo.Colors = ProtocolRDP.RDPColors.Colors15Bit; - break; - case "16": - connectionInfo.Colors = ProtocolRDP.RDPColors.Colors16Bit; - break; - case "24": - connectionInfo.Colors = ProtocolRDP.RDPColors.Colors24Bit; - break; - case "32": - connectionInfo.Colors = ProtocolRDP.RDPColors.Colors32Bit; - break; - } - break; - case "bitmapcachepersistenable": - if (value == "1") - { - connectionInfo.CacheBitmaps = true; - } - else - { - connectionInfo.CacheBitmaps = false; - } - break; - case "screen mode id": - if (value == "2") - { - connectionInfo.Resolution = ProtocolRDP.RDPResolutions.Fullscreen; - } - else - { - connectionInfo.Resolution = ProtocolRDP.RDPResolutions.FitToWindow; - } - break; - case "connect to console": - if (value == "1") - { - connectionInfo.UseConsoleSession = true; - } - break; - case "disable wallpaper": - if (value == "1") - { - connectionInfo.DisplayWallpaper = true; - } - else - { - connectionInfo.DisplayWallpaper = false; - } - break; - case "disable themes": - if (value == "1") - { - connectionInfo.DisplayThemes = true; - } - else - { - connectionInfo.DisplayThemes = false; - } - break; - case "allow font smoothing": - if (value == "1") - { - connectionInfo.EnableFontSmoothing = true; - } - else - { - connectionInfo.EnableFontSmoothing = false; - } - break; - case "allow desktop composition": - if (value == "1") - { - connectionInfo.EnableDesktopComposition = true; - } - else - { - connectionInfo.EnableDesktopComposition = false; - } - break; - case "redirectsmartcards": - if (value == "1") - { - connectionInfo.RedirectSmartCards = true; - } - else - { - connectionInfo.RedirectSmartCards = false; - } - break; - case "redirectdrives": - if (value == "1") - { - connectionInfo.RedirectDiskDrives = true; - } - else - { - connectionInfo.RedirectDiskDrives = false; - } - break; - case "redirectcomports": - if (value == "1") - { - connectionInfo.RedirectPorts = true; - } - else - { - connectionInfo.RedirectPorts = false; - } - break; - case "redirectprinters": - if (value == "1") - { - connectionInfo.RedirectPrinters = true; - } - else - { - connectionInfo.RedirectPrinters = false; - } - break; - case "audiomode": - switch (value) - { - case "0": - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.BringToThisComputer; - break; - case "1": - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.LeaveAtRemoteComputer; - break; - case "2": - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.DoNotPlay; - break; - } - break; - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/RemoteDesktopConnectionImporter.cs b/mRemoteV1/Config/Import/RemoteDesktopConnectionImporter.cs new file mode 100644 index 000000000..81f7ab7fd --- /dev/null +++ b/mRemoteV1/Config/Import/RemoteDesktopConnectionImporter.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; +using System.Linq; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Container; + + +namespace mRemoteNG.Config.Import +{ + public class RemoteDesktopConnectionImporter : IConnectionImporter + { + public void Import(object fileName, ContainerInfo destinationContainer) + { + var fileNameAsString = fileName as string; + if(fileNameAsString == null) + return; + if (File.Exists(fileNameAsString)) + Import(fileNameAsString, destinationContainer); + } + + public void Import(string fileName, ContainerInfo destinationContainer) + { + var dataProvider = new FileDataProvider(fileName); + var content = dataProvider.Load(); + var lines = content.Split(Environment.NewLine.ToCharArray()); + + var deserializer = new RemoteDesktopConnectionDeserializer(lines); + var connectionTreeModel = deserializer.Deserialize(); + + var importedConnection = connectionTreeModel.RootNodes.First().Children.First(); + + if (importedConnection == null) return; + importedConnection.Name = Path.GetFileNameWithoutExtension(fileName); + destinationContainer.AddChild(importedConnection); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/RemoteDesktopConnectionManager.cs b/mRemoteV1/Config/Import/RemoteDesktopConnectionManager.cs deleted file mode 100644 index 00ef91bf0..000000000 --- a/mRemoteV1/Config/Import/RemoteDesktopConnectionManager.cs +++ /dev/null @@ -1,387 +0,0 @@ -using System; -using System.Windows.Forms; -using System.Xml; -using System.IO; -using System.Runtime.InteropServices; -using mRemoteNG.App; -using mRemoteNG.Connection.Protocol.RDP; -using mRemoteNG.Connection; -using mRemoteNG.Container; -using mRemoteNG.Tree; - -namespace mRemoteNG.Config.Import -{ - public class RemoteDesktopConnectionManager - { - public static void Import(string fileName, TreeNode parentTreeNode) - { - XmlDocument xmlDocument = new XmlDocument(); - xmlDocument.Load(fileName); - - XmlNode rdcManNode = xmlDocument.SelectSingleNode("/RDCMan"); - int schemaVersion = Convert.ToInt32(rdcManNode.Attributes["schemaVersion"].Value); - if (!(schemaVersion == 1)) - { - throw (new FileFormatException(string.Format("Unsupported schema version ({0}).", schemaVersion))); - } - - XmlNode versionNode = rdcManNode.SelectSingleNode("./version"); - Version version = new Version(versionNode.InnerText); - if (!(version == new Version(2, 2))) - { - throw (new FileFormatException(string.Format("Unsupported file version ({0}).", version))); - } - - XmlNode fileNode = rdcManNode.SelectSingleNode("./file"); - ImportFileOrGroup(fileNode, parentTreeNode); - } - - private static void ImportFileOrGroup(XmlNode xmlNode, TreeNode parentTreeNode) - { - XmlNode propertiesNode = xmlNode.SelectSingleNode("./properties"); - string name = propertiesNode.SelectSingleNode("./name").InnerText; - - TreeNode treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); - - ContainerInfo containerInfo = new ContainerInfo(); - containerInfo.TreeNode = treeNode; - containerInfo.Name = name; - - ConnectionInfo connectionInfo = ConnectionInfoFromXml(propertiesNode); - connectionInfo.Parent = containerInfo; - connectionInfo.IsContainer = true; - containerInfo.CopyFrom(connectionInfo); - - // We can only inherit from a container node, not the root node or connection nodes - if (ConnectionTreeNode.GetNodeType(parentTreeNode) == TreeNodeType.Container) - { - containerInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - } - else - { - connectionInfo.Inheritance.DisableInheritance(); - } - - treeNode.Name = name; - treeNode.Tag = containerInfo; - treeNode.ImageIndex = (int)TreeImageType.Container; - treeNode.SelectedImageIndex = (int)TreeImageType.Container; - - foreach (XmlNode childNode in xmlNode.SelectNodes("./group|./server")) - { - switch (childNode.Name) - { - case "group": - ImportFileOrGroup(childNode, treeNode); - break; - case "server": - ImportServer(childNode, treeNode); - break; - } - } - - containerInfo.IsExpanded = bool.Parse(propertiesNode.SelectSingleNode("./expanded").InnerText); - if (containerInfo.IsExpanded) - { - treeNode.Expand(); - } - - Runtime.ContainerList.Add(containerInfo); - } - - private static void ImportServer(XmlNode serverNode, TreeNode parentTreeNode) - { - string name = serverNode.SelectSingleNode("./displayName").InnerText; - TreeNode treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); - - ConnectionInfo connectionInfo = ConnectionInfoFromXml(serverNode); - connectionInfo.TreeNode = treeNode; - connectionInfo.Parent = (ContainerInfo)parentTreeNode.Tag; - - treeNode.Name = name; - treeNode.Tag = connectionInfo; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - - Runtime.ConnectionList.Add(connectionInfo); - } - - private static ConnectionInfo ConnectionInfoFromXml(XmlNode xmlNode) - { - ConnectionInfo connectionInfo = new ConnectionInfo(); - connectionInfo.Inheritance = new ConnectionInfoInheritance(connectionInfo); - - string name = xmlNode.SelectSingleNode("./name").InnerText; - - string displayName = ""; - XmlNode displayNameNode = xmlNode.SelectSingleNode("./displayName"); - if (displayNameNode == null) - { - displayName = name; - } - else - { - displayName = displayNameNode.InnerText; - } - - connectionInfo.Name = displayName; - connectionInfo.Description = xmlNode.SelectSingleNode("./comment").InnerText; - connectionInfo.Hostname = name; - - XmlNode logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials"); - if (logonCredentialsNode.Attributes["inherit"].Value == "None") - { - connectionInfo.Username = logonCredentialsNode.SelectSingleNode("userName").InnerText; - - XmlNode passwordNode = logonCredentialsNode.SelectSingleNode("./password"); - if (passwordNode.Attributes["storeAsClearText"].Value == "True") - { - connectionInfo.Password = passwordNode.InnerText; - } - else - { - connectionInfo.Password = DecryptPassword(passwordNode.InnerText); - } - - connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain").InnerText; - } - else - { - connectionInfo.Inheritance.Username = true; - connectionInfo.Inheritance.Password = true; - connectionInfo.Inheritance.Domain = true; - } - - XmlNode connectionSettingsNode = xmlNode.SelectSingleNode("./connectionSettings"); - if (connectionSettingsNode.Attributes["inherit"].Value == "None") - { - connectionInfo.UseConsoleSession = bool.Parse(connectionSettingsNode.SelectSingleNode("./connectToConsole").InnerText); - // ./startProgram - // ./workingDir - connectionInfo.Port = Convert.ToInt32(connectionSettingsNode.SelectSingleNode("./port").InnerText); - } - else - { - connectionInfo.Inheritance.UseConsoleSession = true; - connectionInfo.Inheritance.Port = true; - } - - XmlNode gatewaySettingsNode = xmlNode.SelectSingleNode("./gatewaySettings"); - if (gatewaySettingsNode.Attributes["inherit"].Value == "None") - { - if (gatewaySettingsNode.SelectSingleNode("./enabled").InnerText == "True") - { - connectionInfo.RDGatewayUsageMethod = ProtocolRDP.RDGatewayUsageMethod.Always; - } - else - { - connectionInfo.RDGatewayUsageMethod = ProtocolRDP.RDGatewayUsageMethod.Never; - } - - connectionInfo.RDGatewayHostname = gatewaySettingsNode.SelectSingleNode("./hostName").InnerText; - connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName").InnerText; - - XmlNode passwordNode = logonCredentialsNode.SelectSingleNode("./password"); - if (passwordNode.Attributes["storeAsClearText"].Value == "True") - { - connectionInfo.RDGatewayPassword = passwordNode.InnerText; - } - else - { - connectionInfo.Password = DecryptPassword(passwordNode.InnerText); - } - - connectionInfo.RDGatewayDomain = gatewaySettingsNode.SelectSingleNode("./domain").InnerText; - // ./logonMethod - // ./localBypass - // ./credSharing - } - else - { - connectionInfo.Inheritance.RDGatewayUsageMethod = true; - connectionInfo.Inheritance.RDGatewayHostname = true; - connectionInfo.Inheritance.RDGatewayUsername = true; - connectionInfo.Inheritance.RDGatewayPassword = true; - connectionInfo.Inheritance.RDGatewayDomain = true; - } - - XmlNode remoteDesktopNode = xmlNode.SelectSingleNode("./remoteDesktop"); - if (remoteDesktopNode.Attributes["inherit"].Value == "None") - { - string resolutionString = Convert.ToString(remoteDesktopNode.SelectSingleNode("./size").InnerText.Replace(" ", "")); - try - { - connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), "Res" + resolutionString); - } - catch (ArgumentException) - { - connectionInfo.Resolution = ProtocolRDP.RDPResolutions.FitToWindow; - } - - if (remoteDesktopNode.SelectSingleNode("./sameSizeAsClientArea").InnerText == "True") - { - connectionInfo.Resolution = ProtocolRDP.RDPResolutions.FitToWindow; - } - - if (remoteDesktopNode.SelectSingleNode("./fullScreen").InnerText == "True") - { - connectionInfo.Resolution = ProtocolRDP.RDPResolutions.Fullscreen; - } - - - connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors), remoteDesktopNode.SelectSingleNode("./colorDepth").InnerText); - } - else - { - connectionInfo.Inheritance.Resolution = true; - connectionInfo.Inheritance.Colors = true; - } - - XmlNode localResourcesNode = xmlNode.SelectSingleNode("./localResources"); - if (localResourcesNode.Attributes["inherit"].Value == "None") - { - switch (localResourcesNode.SelectSingleNode("./audioRedirection").InnerText) - { - case "0": // Bring to this computer - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.BringToThisComputer; - break; - case "1": // Leave at remote computer - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.LeaveAtRemoteComputer; - break; - case "2": // Do not play - connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.DoNotPlay; - break; - } - - // ./audioRedirectionQuality - // ./audioCaptureRedirection - - switch (localResourcesNode.SelectSingleNode("./keyboardHook").InnerText) - { - case "0": // On the local computer - connectionInfo.RedirectKeys = false; - break; - case "1": // On the remote computer - connectionInfo.RedirectKeys = true; - break; - case "2": // In full screen mode only - connectionInfo.RedirectKeys = false; - break; - } - - // ./redirectClipboard - connectionInfo.RedirectDiskDrives = bool.Parse(localResourcesNode.SelectSingleNode("./redirectDrives").InnerText); - connectionInfo.RedirectPorts = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPorts").InnerText); - connectionInfo.RedirectPrinters = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPrinters").InnerText); - connectionInfo.RedirectSmartCards = bool.Parse(localResourcesNode.SelectSingleNode("./redirectSmartCards").InnerText); - } - else - { - connectionInfo.Inheritance.RedirectSound = true; - connectionInfo.Inheritance.RedirectKeys = true; - connectionInfo.Inheritance.RedirectDiskDrives = true; - connectionInfo.Inheritance.RedirectPorts = true; - connectionInfo.Inheritance.RedirectPrinters = true; - connectionInfo.Inheritance.RedirectSmartCards = true; - } - - XmlNode securitySettingsNode = xmlNode.SelectSingleNode("./securitySettings"); - if (securitySettingsNode.Attributes["inherit"].Value == "None") - { - switch (securitySettingsNode.SelectSingleNode("./authentication").InnerText) - { - case "0": // No authentication - connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.NoAuth; - break; - case "1": // Do not connect if authentication fails - connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.AuthRequired; - break; - case "2": // Warn if authentication fails - connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.WarnOnFailedAuth; - break; - } - } - else - { - connectionInfo.Inheritance.RDPAuthenticationLevel = true; - } - - // ./displaySettings/thumbnailScale - // ./displaySettings/liveThumbnailUpdates - // ./displaySettings/showDisconnectedThumbnails - - return connectionInfo; - } - - private static string DecryptPassword(string ciphertext) - { - if (string.IsNullOrEmpty(ciphertext)) - { - return null; - } - - GCHandle gcHandle = new GCHandle(); - NativeMethods.DATA_BLOB plaintextData = new NativeMethods.DATA_BLOB(); - try - { - byte[] ciphertextArray = Convert.FromBase64String(ciphertext); - gcHandle = GCHandle.Alloc(ciphertextArray, GCHandleType.Pinned); - - NativeMethods.DATA_BLOB ciphertextData = new NativeMethods.DATA_BLOB(); - ciphertextData.cbData = ciphertextArray.Length; - ciphertextData.pbData = gcHandle.AddrOfPinnedObject(); - - NativeMethods.DATA_BLOB temp_optionalEntropy = new NativeMethods.DATA_BLOB(); - IntPtr temp_promptStruct = IntPtr.Zero; - if (!NativeMethods.CryptUnprotectData(ref ciphertextData, null, ref temp_optionalEntropy, IntPtr.Zero, ref temp_promptStruct, 0, ref plaintextData)) - { - return null; - } - - int plaintextLength = (int) ((double) plaintextData.cbData / 2); // Char = 2 bytes - char[] plaintextArray = new char[plaintextLength - 1 + 1]; - Marshal.Copy(plaintextData.pbData, plaintextArray, 0, plaintextLength); - - return new string(plaintextArray); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage(message: "RemoteDesktopConnectionManager.DecryptPassword() failed.", ex: ex, logOnly: true); - return null; - } - finally - { - if (gcHandle.IsAllocated) - { - gcHandle.Free(); - } - if (!(plaintextData.pbData == IntPtr.Zero)) - { - NativeMethods.LocalFree(plaintextData.pbData); - } - } - } - - // ReSharper disable once ClassNeverInstantiated.Local - private class NativeMethods - { - // ReSharper disable InconsistentNaming - // ReSharper disable IdentifierTypo - // ReSharper disable StringLiteralTypo - [DllImport("crypt32.dll", CharSet = CharSet.Unicode)]public static extern bool CryptUnprotectData(ref DATA_BLOB dataIn, string description, ref DATA_BLOB optionalEntropy, IntPtr reserved, ref IntPtr promptStruct, int flags, ref DATA_BLOB dataOut); - - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]public static extern void LocalFree(IntPtr ptr); - - public struct DATA_BLOB - { - public int cbData; - public IntPtr pbData; - } - // ReSharper restore StringLiteralTypo - // ReSharper restore IdentifierTypo - // ReSharper restore InconsistentNaming - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/RemoteDesktopConnectionManagerImporter.cs b/mRemoteV1/Config/Import/RemoteDesktopConnectionManagerImporter.cs new file mode 100644 index 000000000..60ff988f0 --- /dev/null +++ b/mRemoteV1/Config/Import/RemoteDesktopConnectionManagerImporter.cs @@ -0,0 +1,35 @@ +using System.IO; +using System.Linq; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; +using mRemoteNG.Container; + + +namespace mRemoteNG.Config.Import +{ + public class RemoteDesktopConnectionManagerImporter : IConnectionImporter + { + public void Import(object filePath, ContainerInfo destinationContainer) + { + var fileNameAsString = filePath as string; + if (fileNameAsString == null) + return; + if (File.Exists(fileNameAsString)) + Import(fileNameAsString, destinationContainer); + } + + public void Import(string filePath, ContainerInfo destinationContainer) + { + var dataProvider = new FileDataProvider(filePath); + var fileContent = dataProvider.Load(); + + var deserializer = new RemoteDesktopConnectionManagerDeserializer(fileContent); + var connectionTreeModel = deserializer.Deserialize(); + + var importedRootNode = connectionTreeModel.RootNodes.First(); + if (importedRootNode == null) return; + var childrenToAdd = importedRootNode.Children.ToArray(); + destinationContainer.AddChildRange(childrenToAdd); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Import/mRemoteNGImporter.cs b/mRemoteV1/Config/Import/mRemoteNGImporter.cs index ea8cfe618..ef8fb7d3c 100644 --- a/mRemoteV1/Config/Import/mRemoteNGImporter.cs +++ b/mRemoteV1/Config/Import/mRemoteNGImporter.cs @@ -1,53 +1,42 @@ -using System.Windows.Forms; using System.IO; +using System.Linq; using mRemoteNG.App; -using mRemoteNG.Config.Connections; +using mRemoteNG.Config.DataProviders; +using mRemoteNG.Config.Serializers; using mRemoteNG.Container; -using mRemoteNG.Connection; -using mRemoteNG.Tree; +using mRemoteNG.Messages; + namespace mRemoteNG.Config.Import { // ReSharper disable once InconsistentNaming - public class mRemoteNGImporter + public class mRemoteNGImporter : IConnectionImporter { - public static void Import(string fileName, TreeNode parentTreeNode) + public void Import(object filePath, ContainerInfo destinationContainer) + { + var filePathAsString = filePath as string; + if (filePathAsString == null) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Unable to import file. File path is null."); + return; + } + + if(File.Exists(filePathAsString)) + Import(filePathAsString, destinationContainer); + else + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, $"Unable to import file. File does not exist. Path: {filePathAsString}"); + } + + public void Import(string fileName, ContainerInfo destinationContainer) { - var name = Path.GetFileNameWithoutExtension(fileName); - var treeNode = new TreeNode(name); - parentTreeNode.Nodes.Add(treeNode); + var dataProvider = new FileDataProvider(fileName); + var xmlString = dataProvider.Load(); + var xmlConnectionsDeserializer = new XmlConnectionsDeserializer(xmlString); + var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(true); - var containerInfo = new ContainerInfo - { - TreeNode = treeNode, - Name = name, - IsContainer = true - }; - - containerInfo.Inheritance = new ConnectionInfoInheritance(containerInfo); - - // We can only inherit from a container node, not the root node or connection nodes - var parent = parentTreeNode.Tag as ContainerInfo; - if (parent != null) - containerInfo.Parent = parent; - else - containerInfo.Inheritance.DisableInheritance(); - - treeNode.Name = name; - treeNode.Tag = containerInfo; - treeNode.ImageIndex = (int)TreeImageType.Container; - treeNode.SelectedImageIndex = (int)TreeImageType.Container; - - var connectionsLoad = new ConnectionsLoader - { - ConnectionFileName = fileName, - RootTreeNode = treeNode, - ConnectionList = Runtime.ConnectionList, - ContainerList = Runtime.ContainerList - }; - - connectionsLoad.LoadConnections(true); - Runtime.ContainerList.Add(containerInfo); + var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) }; + rootImportContainer.Children.AddRange(connectionTreeModel.RootNodes.First().Children); + destinationContainer.AddChild(rootImportContainer); } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/AbstractPuttySessionsProvider.cs b/mRemoteV1/Config/Putty/AbstractPuttySessionsProvider.cs new file mode 100644 index 000000000..999a27253 --- /dev/null +++ b/mRemoteV1/Config/Putty/AbstractPuttySessionsProvider.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Root.PuttySessions; + + +namespace mRemoteNG.Config.Putty +{ + public abstract class AbstractPuttySessionsProvider + { + public virtual RootPuttySessionsNodeInfo RootInfo { get; } = new RootPuttySessionsNodeInfo(); + protected virtual List Sessions => RootInfo.Children.OfType().ToList(); + + #region Public Methods + public abstract string[] GetSessionNames(bool raw = false); + public abstract PuttySessionInfo GetSession(string sessionName); + + public virtual IEnumerable GetSessions() + { + var sessionNamesFromProvider = GetSessionNames(true); + foreach (var sessionName in GetSessionNamesToAdd(sessionNamesFromProvider)) + { + var sessionInfo = GetSession(sessionName); + AddSession(sessionInfo); + } + foreach (var session in GetSessionToRemove(sessionNamesFromProvider)) + { + RemoveSession(session); + } + RootInfo.SortRecursive(); + return Sessions; + } + + private IEnumerable GetSessionNamesToAdd(IEnumerable sessionNamesFromProvider) + { + var currentlyKnownSessionNames = Sessions.Select(session => session.Name); + var sessionNamesToAdd = sessionNamesFromProvider.Except(currentlyKnownSessionNames); + return sessionNamesToAdd; + } + + private IEnumerable GetSessionToRemove(IEnumerable sessionNamesFromProvider) + { + var currentlyKnownSessionNames = Sessions.Select(session => session.Name); + var sessionNamesToRemove = currentlyKnownSessionNames.Except(sessionNamesFromProvider); + return Sessions.Where(session => sessionNamesToRemove.Contains(session.Name)); + } + + protected virtual void AddSession(PuttySessionInfo sessionInfo) + { + if (string.IsNullOrEmpty(sessionInfo?.Name) || Sessions.Any(child => child.Name == sessionInfo.Name)) + return; + RootInfo.AddChild(sessionInfo); + RaisePuttySessionCollectionChangedEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, sessionInfo)); + } + + protected virtual void RemoveSession(PuttySessionInfo sessionInfo) + { + if (!Sessions.Contains(sessionInfo)) return; + RootInfo.RemoveChild(sessionInfo); + RaisePuttySessionCollectionChangedEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, sessionInfo)); + } + + public virtual void StartWatcher() { } + + public virtual void StopWatcher() { } + #endregion + + public delegate void PuttySessionChangedEventHandler(object sender, PuttySessionChangedEventArgs e); + public event PuttySessionChangedEventHandler PuttySessionChanged; + protected virtual void RaiseSessionChangedEvent(PuttySessionChangedEventArgs args) + { + PuttySessionChanged?.Invoke(this, args); + } + + public event NotifyCollectionChangedEventHandler PuttySessionsCollectionChanged; + protected void RaisePuttySessionCollectionChangedEvent(NotifyCollectionChangedEventArgs args) + { + PuttySessionsCollectionChanged?.Invoke(this, args); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/Config.Putty.Provider.cs b/mRemoteV1/Config/Putty/Config.Putty.Provider.cs deleted file mode 100644 index a3eb9ea56..000000000 --- a/mRemoteV1/Config/Putty/Config.Putty.Provider.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Collections.Generic; -using System; -using System.Windows.Forms; -using mRemoteNG.Tree; -using mRemoteNG.Connection; - - -namespace mRemoteNG.Config.Putty -{ - public abstract class Provider - { - #region Public Methods - private TreeNode _rootTreeNode; - public TreeNode RootTreeNode - { - get - { - if (_rootTreeNode == null) - { - _rootTreeNode = CreateRootTreeNode(); - } - return _rootTreeNode; - } - } - - private Root.PuttySessions.PuttySessionsNodeInfo _rootInfo; - public Root.PuttySessions.PuttySessionsNodeInfo RootInfo - { - get - { - if (_rootInfo == null) - { - _rootInfo = CreateRootInfo(); - } - return _rootInfo; - } - } - - public abstract string[] GetSessionNames(bool raw = false); - public abstract PuttySessionInfo GetSession(string sessionName); - - public virtual PuttySessionInfo[] GetSessions() - { - List sessionList = new List(); - PuttySessionInfo sessionInfo = (PuttySessionInfo)default(ConnectionInfo); - foreach (string sessionName in GetSessionNames(true)) - { - sessionInfo = GetSession(sessionName); - if (sessionInfo == null || string.IsNullOrEmpty(sessionInfo.Hostname)) - { - continue; - } - sessionList.Add(sessionInfo); - } - return sessionList.ToArray(); - } - - public virtual void StartWatcher() - { - - } - - public virtual void StopWatcher() - { - - } - #endregion - - #region Public Events - public delegate void SessionChangedEventHandler(object sender, SessionChangedEventArgs e); - private SessionChangedEventHandler SessionChangedEvent; - - public event SessionChangedEventHandler SessionChanged - { - add - { - SessionChangedEvent = (SessionChangedEventHandler) System.Delegate.Combine(SessionChangedEvent, value); - } - remove - { - SessionChangedEvent = (SessionChangedEventHandler) System.Delegate.Remove(SessionChangedEvent, value); - } - } - #endregion - - #region Public Classes - public class SessionChangedEventArgs : EventArgs - { - } - #endregion - - #region Protected Methods - private delegate TreeNode CreateRootTreeNodeDelegate(); - protected virtual TreeNode CreateRootTreeNode() - { - TreeView treeView = ConnectionTree.TreeView; - if (treeView == null) - { - return null; - } - if (treeView.InvokeRequired) - { - return (TreeNode)treeView.Invoke(new CreateRootTreeNodeDelegate(CreateRootTreeNode)); - } - - TreeNode newTreeNode = new TreeNode(); - RootInfo.TreeNode = newTreeNode; - - newTreeNode.Name = _rootInfo.Name; - newTreeNode.Text = _rootInfo.Name; - newTreeNode.Tag = _rootInfo; - newTreeNode.ImageIndex = (int)TreeImageType.PuttySessions; - newTreeNode.SelectedImageIndex = (int)TreeImageType.PuttySessions; - - return newTreeNode; - } - - protected virtual Root.PuttySessions.PuttySessionsNodeInfo CreateRootInfo() - { - Root.PuttySessions.PuttySessionsNodeInfo newRootInfo = new Root.PuttySessions.PuttySessionsNodeInfo(); - - if (string.IsNullOrEmpty(Convert.ToString(mRemoteNG.Settings.Default.PuttySavedSessionsName))) - { - newRootInfo.Name = Language.strPuttySavedSessionsRootName; - } - else - { - newRootInfo.Name = Convert.ToString(mRemoteNG.Settings.Default.PuttySavedSessionsName); - } - - if (string.IsNullOrEmpty(Convert.ToString(mRemoteNG.Settings.Default.PuttySavedSessionsPanel))) - { - newRootInfo.Panel = Language.strGeneral; - } - else - { - newRootInfo.Panel = Convert.ToString(mRemoteNG.Settings.Default.PuttySavedSessionsPanel); - } - - return newRootInfo; - } - - protected virtual void OnSessionChanged(SessionChangedEventArgs e) - { - if (SessionChangedEvent != null) - SessionChangedEvent(this, new SessionChangedEventArgs()); - } - #endregion - } -} \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/Config.Putty.RegistryProvider.cs b/mRemoteV1/Config/Putty/Config.Putty.RegistryProvider.cs deleted file mode 100644 index 7c8be84b1..000000000 --- a/mRemoteV1/Config/Putty/Config.Putty.RegistryProvider.cs +++ /dev/null @@ -1,168 +0,0 @@ -using Microsoft.Win32; -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Connection.Protocol; -using mRemoteNG.Messages; -using System; -using System.Collections.Generic; -using System.Management; -using System.Security.Principal; - - -namespace mRemoteNG.Config.Putty -{ - public class RegistryProvider : Provider - { - #region Private Fields - private const string PuttySessionsKey = "Software\\SimonTatham\\PuTTY\\Sessions"; - private static ManagementEventWatcher _eventWatcher; - #endregion - - #region Public Methods - public override string[] GetSessionNames(bool raw = false) - { - RegistryKey sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey); - if (sessionsKey == null) - { - return new string[] {}; - } - - List sessionNames = new List(); - foreach (string sessionName in sessionsKey.GetSubKeyNames()) - { - if (raw) - { - sessionNames.Add(sessionName); - } - else - { - sessionNames.Add(System.Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B"))); - } - } - - if (raw) - { - if (!sessionNames.Contains("Default%20Settings")) // Do not localize - { - sessionNames.Insert(0, "Default%20Settings"); - } - } - else - { - if (!sessionNames.Contains("Default Settings")) - { - sessionNames.Insert(0, "Default Settings"); - } - } - - return sessionNames.ToArray(); - } - - public override PuttySessionInfo GetSession(string sessionName) - { - RegistryKey sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey); - if (sessionsKey == null) - { - return null; - } - - RegistryKey sessionKey = sessionsKey.OpenSubKey(sessionName); - if (sessionKey == null) - { - return null; - } - - sessionName = System.Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")); - - PuttySessionInfo sessionInfo = new PuttySessionInfo(); - sessionInfo.PuttySession = sessionName; - sessionInfo.Name = sessionName; - sessionInfo.Hostname = Convert.ToString(sessionKey.GetValue("HostName")); - sessionInfo.Username = Convert.ToString(sessionKey.GetValue("UserName")); - string protocol = Convert.ToString(sessionKey.GetValue("Protocol")); - if (protocol == null) - { - protocol = "ssh"; - } - switch (protocol.ToLowerInvariant()) - { - case "raw": - sessionInfo.Protocol = ProtocolType.RAW; - break; - case "rlogin": - sessionInfo.Protocol = ProtocolType.Rlogin; - break; - case "serial": - return null; - case "ssh": - object sshVersionObject = sessionKey.GetValue("SshProt"); - if (sshVersionObject != null) - { - int sshVersion = Convert.ToInt32(sshVersionObject); - if (sshVersion >= 2) - { - sessionInfo.Protocol = ProtocolType.SSH2; - } - else - { - sessionInfo.Protocol = ProtocolType.SSH1; - } - } - else - { - sessionInfo.Protocol = ProtocolType.SSH2; - } - break; - case "telnet": - sessionInfo.Protocol = ProtocolType.Telnet; - break; - default: - return null; - } - sessionInfo.Port = Convert.ToInt32(sessionKey.GetValue("PortNumber")); - - return sessionInfo; - } - - public override void StartWatcher() - { - if (_eventWatcher != null) - { - return ; - } - - try - { - string currentUserSid = WindowsIdentity.GetCurrent().User.Value; - string key = Convert.ToString(string.Join("\\", new[] {currentUserSid, PuttySessionsKey}).Replace("\\", "\\\\")); - WqlEventQuery query = new WqlEventQuery(string.Format("SELECT * FROM RegistryTreeChangeEvent WHERE Hive = \'HKEY_USERS\' AND RootPath = \'{0}\'", key)); - _eventWatcher = new ManagementEventWatcher(query); - _eventWatcher.EventArrived += OnManagementEventArrived; - _eventWatcher.Start(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage("PuttySessions.Watcher.StartWatching() failed.", ex, MessageClass.WarningMsg, true); - } - } - - public override void StopWatcher() - { - if (_eventWatcher == null) - { - return ; - } - _eventWatcher.Stop(); - _eventWatcher.Dispose(); - _eventWatcher = null; - } - #endregion - - #region Private Methods - private void OnManagementEventArrived(object sender, EventArrivedEventArgs e) - { - OnSessionChanged(new SessionChangedEventArgs()); - } - #endregion - } -} diff --git a/mRemoteV1/Config/Putty/Config.Putty.Sessions.cs b/mRemoteV1/Config/Putty/Config.Putty.Sessions.cs deleted file mode 100644 index eba31b4e0..000000000 --- a/mRemoteV1/Config/Putty/Config.Putty.Sessions.cs +++ /dev/null @@ -1,231 +0,0 @@ -using mRemoteNG.Connection; -using mRemoteNG.Tools; -using mRemoteNG.Tree; -using System.Collections.Generic; -using System.ComponentModel; -using System.Windows.Forms; - - -namespace mRemoteNG.Config.Putty -{ - public class Sessions - { - #region Public Methods - private delegate void AddSessionsToTreeDelegate(); - public static void AddSessionsToTree() - { - TreeView treeView = ConnectionTree.TreeView; - if (treeView == null) - { - return ; - } - if (treeView.InvokeRequired) - { - treeView.Invoke(new AddSessionsToTreeDelegate(AddSessionsToTree)); - return ; - } - - foreach (Provider provider in Providers) - { - TreeNode rootTreeNode = provider.RootTreeNode; - bool inUpdate = false; - - List savedSessions = new List(provider.GetSessions()); - if (!IsProviderEnabled(provider) || savedSessions == null || savedSessions.Count == 0) - { - if (rootTreeNode != null && treeView.Nodes.Contains(rootTreeNode)) - { - treeView.BeginUpdate(); - treeView.Nodes.Remove(rootTreeNode); - treeView.EndUpdate(); - } - continue; - } - - if (!treeView.Nodes.Contains(rootTreeNode)) - { - if (!inUpdate) - { - treeView.BeginUpdate(); - inUpdate = true; - } - treeView.Nodes.Add(rootTreeNode); - } - - List newTreeNodes = new List(); - foreach (PuttySessionInfo sessionInfo in savedSessions) - { - TreeNode treeNode = default(TreeNode); - bool isNewNode = false; - if (rootTreeNode.Nodes.ContainsKey(sessionInfo.Name)) - { - treeNode = rootTreeNode.Nodes[sessionInfo.Name]; - isNewNode = false; - } - else - { - treeNode = ConnectionTreeNode.AddNode(TreeNodeType.PuttySession, sessionInfo.Name); - if (treeNode == null) - { - continue; - } - treeNode.Name = treeNode.Text; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - isNewNode = true; - } - - sessionInfo.RootPuttySessionsInfo = provider.RootInfo; - sessionInfo.TreeNode = treeNode; - //sessionInfo.IInheritable.TurnOffInheritanceCompletely(); - - treeNode.Tag = sessionInfo; - - if (isNewNode) - { - newTreeNodes.Add(treeNode); - } - } - - foreach (TreeNode treeNode in rootTreeNode.Nodes) - { - if (!savedSessions.Contains((ConnectionInfo)treeNode.Tag)) - { - if (!inUpdate) - { - treeView.BeginUpdate(); - inUpdate = true; - } - rootTreeNode.Nodes.Remove(treeNode); - } - } - - if (!(newTreeNodes.Count == 0)) - { - if (!inUpdate) - { - treeView.BeginUpdate(); - inUpdate = true; - } - rootTreeNode.Nodes.AddRange(newTreeNodes.ToArray()); - } - - if (inUpdate) - { - ConnectionTree.Sort(rootTreeNode, SortOrder.Ascending); - rootTreeNode.Expand(); - treeView.EndUpdate(); - } - } - } - - public static void StartWatcher() - { - foreach (Provider provider in Providers) - { - provider.StartWatcher(); - provider.SessionChanged += SessionChanged; - } - } - - public static void StopWatcher() - { - foreach (Provider provider in Providers) - { - provider.StopWatcher(); - provider.SessionChanged -= SessionChanged; - } - } - - public static void SessionChanged(object sender, Provider.SessionChangedEventArgs e) - { - AddSessionsToTree(); - } - #endregion - - #region Private Methods - private static List _providers; - private static List Providers - { - get - { - if (_providers == null || _providers.Count == 0) - { - AddProviders(); - } - return _providers; - } - } - - private static void AddProviders() - { - _providers = new List(); - _providers.Add(new RegistryProvider()); - _providers.Add(new XmingProvider()); - } - - private static string[] GetSessionNames(bool raw = false) - { - List sessionNames = new List(); - foreach (Provider provider in Providers) - { - if (!IsProviderEnabled(provider)) - { - continue; - } - sessionNames.AddRange(provider.GetSessionNames(raw)); - } - return sessionNames.ToArray(); - } - - private static bool IsProviderEnabled(Provider provider) - { - bool enabled = true; - if (PuttyTypeDetector.GetPuttyType() == PuttyTypeDetector.PuttyType.Xming) - { - if ((provider) is RegistryProvider) - { - enabled = false; - } - } - else - { - if ((provider) is XmingProvider) - { - enabled = false; - } - } - return enabled; - } - #endregion - - #region Public Classes - public class SessionList : StringConverter - { - - public static string[] Names - { - get - { - return GetSessionNames(); - } - } - - public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) - { - return new StandardValuesCollection(Names); - } - - public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context) - { - return true; - } - - public override bool GetStandardValuesSupported(ITypeDescriptorContext context) - { - return true; - } - } - #endregion - } -} diff --git a/mRemoteV1/Config/Putty/PuttySessionChangedEventArgs.cs b/mRemoteV1/Config/Putty/PuttySessionChangedEventArgs.cs new file mode 100644 index 000000000..febb5f425 --- /dev/null +++ b/mRemoteV1/Config/Putty/PuttySessionChangedEventArgs.cs @@ -0,0 +1,16 @@ +using System; +using mRemoteNG.Connection; + + +namespace mRemoteNG.Config.Putty +{ + public class PuttySessionChangedEventArgs : EventArgs + { + public PuttySessionInfo Session { get; set; } + + public PuttySessionChangedEventArgs(PuttySessionInfo sessionChanged = null) + { + Session = sessionChanged; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/PuttySessionsManager.cs b/mRemoteV1/Config/Putty/PuttySessionsManager.cs new file mode 100644 index 000000000..19f293f1c --- /dev/null +++ b/mRemoteV1/Config/Putty/PuttySessionsManager.cs @@ -0,0 +1,156 @@ +using mRemoteNG.Tools; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using mRemoteNG.Root.PuttySessions; + + +namespace mRemoteNG.Config.Putty +{ + public class PuttySessionsManager + { + public static PuttySessionsManager Instance { get; } = new PuttySessionsManager(); + + private readonly List _providers = new List(); + public IEnumerable Providers => _providers; + public List RootPuttySessionsNodes { get; } = new List(); + + private PuttySessionsManager() + { + AddProvider(new PuttySessionsRegistryProvider()); + AddProvider(new PuttySessionsXmingProvider()); + } + + + #region Public Methods + public void AddSessions() + { + foreach (var provider in Providers) + { + AddSessionsFromProvider(provider); + } + } + + private void AddSessionsFromProvider(AbstractPuttySessionsProvider provider) + { + var rootTreeNode = provider.RootInfo; + provider.GetSessions(); + + if (!RootPuttySessionsNodes.Contains(rootTreeNode) && rootTreeNode.HasChildren()) + RootPuttySessionsNodes.Add(rootTreeNode); + rootTreeNode.SortRecursive(); + } + + public void StartWatcher() + { + foreach (var provider in Providers) + { + provider.StartWatcher(); + provider.PuttySessionChanged += PuttySessionChanged; + } + } + + public void StopWatcher() + { + foreach (var provider in Providers) + { + provider.StopWatcher(); + provider.PuttySessionChanged -= PuttySessionChanged; + } + } + + public void AddProvider(AbstractPuttySessionsProvider newProvider) + { + if (_providers.Contains(newProvider)) return; + _providers.Add(newProvider); + newProvider.PuttySessionsCollectionChanged += RaisePuttySessionCollectionChangedEvent; + RaiseSessionProvidersCollectionChangedEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newProvider)); + } + + public void AddProviders(IEnumerable newProviders) + { + foreach (var provider in newProviders) + AddProvider(provider); + } + + public void RemoveProvider(AbstractPuttySessionsProvider providerToRemove) + { + if (!_providers.Contains(providerToRemove)) return; + _providers.Remove(providerToRemove); + providerToRemove.PuttySessionsCollectionChanged -= RaisePuttySessionCollectionChangedEvent; + RaiseSessionProvidersCollectionChangedEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, providerToRemove)); + } + + public void PuttySessionChanged(object sender, PuttySessionChangedEventArgs e) + { + AddSessions(); + } + #endregion + + #region Private Methods + private string[] GetSessionNames(bool raw = false) + { + var sessionNames = new List(); + foreach (var provider in Providers) + { + if (!IsProviderEnabled(provider)) + { + continue; + } + sessionNames.AddRange(provider.GetSessionNames(raw)); + } + return sessionNames.ToArray(); + } + + private bool IsProviderEnabled(AbstractPuttySessionsProvider puttySessionsProvider) + { + var enabled = true; + if (PuttyTypeDetector.GetPuttyType() == PuttyTypeDetector.PuttyType.Xming) + { + if (puttySessionsProvider is PuttySessionsRegistryProvider) + enabled = false; + } + else + { + if (puttySessionsProvider is PuttySessionsXmingProvider) + enabled = false; + } + return enabled; + } + #endregion + + #region Public Classes + public class SessionList : StringConverter + { + public static string[] Names => Instance.GetSessionNames(); + + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + return new StandardValuesCollection(Names); + } + + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + } + #endregion + + public event NotifyCollectionChangedEventHandler PuttySessionsCollectionChanged; + protected void RaisePuttySessionCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args) + { + PuttySessionsCollectionChanged?.Invoke(sender, args); + } + + public event NotifyCollectionChangedEventHandler SessionProvidersCollectionChanged; + protected void RaiseSessionProvidersCollectionChangedEvent(NotifyCollectionChangedEventArgs args) + { + SessionProvidersCollectionChanged?.Invoke(this, args); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/PuttySessionsRegistryProvider.cs b/mRemoteV1/Config/Putty/PuttySessionsRegistryProvider.cs new file mode 100644 index 000000000..7956a757c --- /dev/null +++ b/mRemoteV1/Config/Putty/PuttySessionsRegistryProvider.cs @@ -0,0 +1,122 @@ +using Microsoft.Win32; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Messages; +using System; +using System.Collections.Generic; +using System.Management; +using System.Security.Principal; +using System.Web; + + +namespace mRemoteNG.Config.Putty +{ + public class PuttySessionsRegistryProvider : AbstractPuttySessionsProvider + { + private const string PuttySessionsKey = "Software\\SimonTatham\\PuTTY\\Sessions"; + private static ManagementEventWatcher _eventWatcher; + + #region Public Methods + public override string[] GetSessionNames(bool raw = false) + { + var sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey); + if (sessionsKey == null) return new string[] {}; + + var sessionNames = new List(); + foreach (var sessionName in sessionsKey.GetSubKeyNames()) + { + sessionNames.Add(raw ? sessionName : HttpUtility.UrlDecode(sessionName.Replace("+", "%2B"))); + } + + if (raw && !sessionNames.Contains("Default%20Settings")) + sessionNames.Insert(0, "Default%20Settings"); + else if (!sessionNames.Contains("Default Settings")) + sessionNames.Insert(0, "Default Settings"); + + return sessionNames.ToArray(); + } + + public override PuttySessionInfo GetSession(string sessionName) + { + var sessionsKey = Registry.CurrentUser.OpenSubKey(PuttySessionsKey); + var sessionKey = sessionsKey?.OpenSubKey(sessionName); + if (sessionKey == null) return null; + + sessionName = HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")); + + var sessionInfo = new PuttySessionInfo + { + PuttySession = sessionName, + Name = sessionName, + Hostname = Convert.ToString(sessionKey.GetValue("HostName")), + Username = Convert.ToString(sessionKey.GetValue("UserName")) + }; + var protocol = Convert.ToString(sessionKey.GetValue("Protocol")) ?? "ssh"; + switch (protocol.ToLowerInvariant()) + { + case "raw": + sessionInfo.Protocol = ProtocolType.RAW; + break; + case "rlogin": + sessionInfo.Protocol = ProtocolType.Rlogin; + break; + case "serial": + return null; + case "ssh": + var sshVersionObject = sessionKey.GetValue("SshProt"); + if (sshVersionObject != null) + { + var sshVersion = Convert.ToInt32(sshVersionObject); + sessionInfo.Protocol = sshVersion >= 2 ? ProtocolType.SSH2 : ProtocolType.SSH1; + } + else + { + sessionInfo.Protocol = ProtocolType.SSH2; + } + break; + case "telnet": + sessionInfo.Protocol = ProtocolType.Telnet; + break; + default: + return null; + } + sessionInfo.Port = Convert.ToInt32(sessionKey.GetValue("PortNumber")); + + return sessionInfo; + } + + public override void StartWatcher() + { + if (_eventWatcher != null) return; + + try + { + var currentUserSid = WindowsIdentity.GetCurrent().User?.Value; + var key = Convert.ToString(string.Join("\\", currentUserSid, PuttySessionsKey).Replace("\\", "\\\\")); + var query = new WqlEventQuery($"SELECT * FROM RegistryTreeChangeEvent WHERE Hive = \'HKEY_USERS\' AND RootPath = \'{key}\'"); + _eventWatcher = new ManagementEventWatcher(query); + _eventWatcher.EventArrived += OnManagementEventArrived; + _eventWatcher.Start(); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage("PuttySessions.Watcher.StartWatching() failed.", ex, MessageClass.WarningMsg, true); + } + } + + public override void StopWatcher() + { + if (_eventWatcher == null) return; + _eventWatcher.Stop(); + _eventWatcher.Dispose(); + _eventWatcher = null; + } + #endregion + + private void OnManagementEventArrived(object sender, EventArrivedEventArgs e) + { + RaiseSessionChangedEvent(new PuttySessionChangedEventArgs()); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Putty/Config.Putty.XmingProvider.cs b/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs similarity index 60% rename from mRemoteV1/Config/Putty/Config.Putty.XmingProvider.cs rename to mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs index bd7872ee8..79278964d 100644 --- a/mRemoteV1/Config/Putty/Config.Putty.XmingProvider.cs +++ b/mRemoteV1/Config/Putty/PuttySessionsXmingProvider.cs @@ -5,44 +5,38 @@ using mRemoteNG.Messages; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text.RegularExpressions; +using mRemoteNG.Root.PuttySessions; namespace mRemoteNG.Config.Putty { - public class XmingProvider : Provider + public class PuttySessionsXmingProvider : AbstractPuttySessionsProvider { - #region Private Fields + public override RootPuttySessionsNodeInfo RootInfo { get; } = new RootPuttySessionsNodeInfo { Name = "Xming Putty Sessions" }; private const string RegistrySessionNameFormat = "{0} [registry]"; private const string RegistrySessionNamePattern = "(.*)\\ \\[registry\\]"; - private static readonly RegistryProvider RegistryProvider = new RegistryProvider(); + private static readonly PuttySessionsRegistryProvider PuttySessionsRegistryProvider = new PuttySessionsRegistryProvider(); private static FileSystemWatcher _eventWatcher; - #endregion #region Public Methods public override string[] GetSessionNames(bool raw = false) { - string sessionsFolderPath = GetSessionsFolderPath(); + var sessionsFolderPath = GetSessionsFolderPath(); if (!Directory.Exists(sessionsFolderPath)) { return new string[] {}; } - List sessionNames = new List(); - foreach (string sessionName in Directory.GetFiles(sessionsFolderPath)) + var sessionNames = new List(); + foreach (var sessionName in Directory.GetFiles(sessionsFolderPath)) { - string _sessionFileName = Path.GetFileName(sessionName); - if (raw) - { - sessionNames.Add(_sessionFileName); - } - else - { - sessionNames.Add(System.Web.HttpUtility.UrlDecode(_sessionFileName.Replace("+", "%2B"))); - } + var sessionFileName = Path.GetFileName(sessionName); + sessionNames.Add(raw ? sessionFileName : System.Web.HttpUtility.UrlDecode(sessionFileName?.Replace("+", "%2B"))); } - - if (raw) + + if (raw) { if (!sessionNames.Contains("Default%20Settings")) // Do not localize { @@ -57,13 +51,9 @@ namespace mRemoteNG.Config.Putty } } - List registrySessionNames = new List(); - foreach (string sessionName in RegistryProvider.GetSessionNames(raw)) - { - registrySessionNames.Add(string.Format(RegistrySessionNameFormat, sessionName)); - } - - sessionNames.AddRange(registrySessionNames); + var registrySessionNames = PuttySessionsRegistryProvider.GetSessionNames(raw).Select(sessionName => string.Format(RegistrySessionNameFormat, sessionName)).ToList(); + + sessionNames.AddRange(registrySessionNames); sessionNames.Sort(); return sessionNames.ToArray(); @@ -71,38 +61,36 @@ namespace mRemoteNG.Config.Putty public override PuttySessionInfo GetSession(string sessionName) { - string registrySessionName = GetRegistrySessionName(sessionName); + var registrySessionName = GetRegistrySessionName(sessionName); if (!string.IsNullOrEmpty(registrySessionName)) { - return ModifyRegistrySessionInfo(RegistryProvider.GetSession(registrySessionName)); + return ModifyRegistrySessionInfo(PuttySessionsRegistryProvider.GetSession(registrySessionName)); } - - string sessionsFolderPath = GetSessionsFolderPath(); + + var sessionsFolderPath = GetSessionsFolderPath(); if (!Directory.Exists(sessionsFolderPath)) { return null; } - - string sessionFile = Path.Combine(sessionsFolderPath, sessionName); + + var sessionFile = Path.Combine(sessionsFolderPath, sessionName); if (!File.Exists(sessionFile)) { return null; } sessionName = System.Web.HttpUtility.UrlDecode(sessionName.Replace("+", "%2B")); - - SessionFileReader sessionFileReader = new SessionFileReader(sessionFile); - PuttySessionInfo sessionInfo = new PuttySessionInfo(); - sessionInfo.PuttySession = sessionName; - sessionInfo.Name = sessionName; - sessionInfo.Hostname = sessionFileReader.GetValue("HostName"); - sessionInfo.Username = sessionFileReader.GetValue("UserName"); - string protocol = sessionFileReader.GetValue("Protocol"); - if (protocol == null) - { - protocol = "ssh"; - } - switch (protocol.ToLowerInvariant()) + + var sessionFileReader = new SessionFileReader(sessionFile); + var sessionInfo = new PuttySessionInfo + { + PuttySession = sessionName, + Name = sessionName, + Hostname = sessionFileReader.GetValue("HostName"), + Username = sessionFileReader.GetValue("UserName") + }; + var protocol = sessionFileReader.GetValue("Protocol") ?? "ssh"; + switch (protocol.ToLowerInvariant()) { case "raw": sessionInfo.Protocol = ProtocolType.RAW; @@ -116,15 +104,8 @@ namespace mRemoteNG.Config.Putty object sshVersionObject = sessionFileReader.GetValue("SshProt"); if (sshVersionObject != null) { - int sshVersion = Convert.ToInt32(sshVersionObject); - if (sshVersion >= 2) - { - sessionInfo.Protocol = ProtocolType.SSH2; - } - else - { - sessionInfo.Protocol = ProtocolType.SSH1; - } + var sshVersion = Convert.ToInt32(sshVersionObject); + sessionInfo.Protocol = sshVersion >= 2 ? ProtocolType.SSH2 : ProtocolType.SSH1; } else { @@ -144,8 +125,8 @@ namespace mRemoteNG.Config.Putty public override void StartWatcher() { - RegistryProvider.StartWatcher(); - RegistryProvider.SessionChanged += OnRegistrySessionChanged; + PuttySessionsRegistryProvider.StartWatcher(); + PuttySessionsRegistryProvider.PuttySessionChanged += OnRegistrySessionChanged; if (_eventWatcher != null) { @@ -154,9 +135,11 @@ namespace mRemoteNG.Config.Putty try { - _eventWatcher = new FileSystemWatcher(GetSessionsFolderPath()); - _eventWatcher.NotifyFilter = (System.IO.NotifyFilters) (NotifyFilters.FileName | NotifyFilters.LastWrite); - _eventWatcher.Changed += OnFileSystemEventArrived; + _eventWatcher = new FileSystemWatcher(GetSessionsFolderPath()) + { + NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite + }; + _eventWatcher.Changed += OnFileSystemEventArrived; _eventWatcher.Created += OnFileSystemEventArrived; _eventWatcher.Deleted += OnFileSystemEventArrived; _eventWatcher.Renamed += OnFileSystemEventArrived; @@ -170,8 +153,8 @@ namespace mRemoteNG.Config.Putty public override void StopWatcher() { - RegistryProvider.StopWatcher(); - RegistryProvider.SessionChanged -= OnRegistrySessionChanged; + PuttySessionsRegistryProvider.StopWatcher(); + PuttySessionsRegistryProvider.PuttySessionChanged -= OnRegistrySessionChanged; if (_eventWatcher == null) { @@ -186,43 +169,31 @@ namespace mRemoteNG.Config.Putty #region Private Methods private static string GetPuttyConfPath() { - string puttyPath = ""; - if (mRemoteNG.Settings.Default.UseCustomPuttyPath) - { - puttyPath = Convert.ToString(mRemoteNG.Settings.Default.CustomPuttyPath); - } - else - { - puttyPath = App.Info.GeneralAppInfo.PuttyPath; - } + var puttyPath = ""; + puttyPath = mRemoteNG.Settings.Default.UseCustomPuttyPath ? Convert.ToString(mRemoteNG.Settings.Default.CustomPuttyPath) : App.Info.GeneralAppInfo.PuttyPath; return Path.Combine(Path.GetDirectoryName(puttyPath), "putty.conf"); } private static string GetSessionsFolderPath() { - string puttyConfPath = GetPuttyConfPath(); - PuttyConfFileReader sessionFileReader = new PuttyConfFileReader(puttyConfPath); - string basePath = Environment.ExpandEnvironmentVariables(sessionFileReader.GetValue("sshk&sess")); + var puttyConfPath = GetPuttyConfPath(); + var sessionFileReader = new PuttyConfFileReader(puttyConfPath); + var basePath = Environment.ExpandEnvironmentVariables(sessionFileReader.GetValue("sshk&sess")); return Path.Combine(basePath, "sessions"); } private static string GetRegistrySessionName(string sessionName) { - Regex regex = new Regex(RegistrySessionNamePattern); - - MatchCollection matches = regex.Matches(sessionName); + var regex = new Regex(RegistrySessionNamePattern); + + var matches = regex.Matches(sessionName); if (matches.Count < 1) { return string.Empty; } - - GroupCollection groups = matches[0].Groups; - if (groups.Count < 1) - { - return string.Empty; // This should always include at least one item, but check anyway - } - - return groups[1].Value; + + var groups = matches[0].Groups; + return groups.Count < 1 ? string.Empty : groups[1].Value; } private static PuttySessionInfo ModifyRegistrySessionInfo(PuttySessionInfo sessionInfo) @@ -234,12 +205,12 @@ namespace mRemoteNG.Config.Putty private void OnFileSystemEventArrived(object sender, FileSystemEventArgs e) { - OnSessionChanged(new SessionChangedEventArgs()); + RaiseSessionChangedEvent(new PuttySessionChangedEventArgs()); } - private void OnRegistrySessionChanged(object sender, SessionChangedEventArgs e) + private void OnRegistrySessionChanged(object sender, PuttySessionChangedEventArgs e) { - OnSessionChanged(new SessionChangedEventArgs()); + RaiseSessionChangedEvent(new PuttySessionChangedEventArgs()); } #endregion @@ -264,12 +235,11 @@ namespace mRemoteNG.Config.Putty { return ; } - using (StreamReader streamReader = new StreamReader(_puttyConfFile)) + using (var streamReader = new StreamReader(_puttyConfFile)) { - string line = ""; - do + do { - line = streamReader.ReadLine(); + var line = streamReader.ReadLine(); if (line == null) { break; @@ -283,7 +253,7 @@ namespace mRemoteNG.Config.Putty { continue; // Comment } - string[] parts = line.Split(new char[] {'='}, 2); + var parts = line.Split(new[] {'='}, 2); if (parts.Length < 2) { continue; @@ -309,11 +279,7 @@ namespace mRemoteNG.Config.Putty { LoadConfiguration(); } - if (!_configuration.ContainsKey(setting)) - { - return string.Empty; - } - return _configuration[setting]; + return !_configuration.ContainsKey(setting) ? string.Empty : _configuration[setting]; } } @@ -339,15 +305,14 @@ namespace mRemoteNG.Config.Putty } using (StreamReader streamReader = new StreamReader(_sessionFile)) { - string line = ""; - do + do { - line = streamReader.ReadLine(); + var line = streamReader.ReadLine(); if (line == null) { break; } - string[] parts = line.Split(new char[] {'\\'}); + var parts = line.Split('\\'); if (parts.Length < 2) { continue; @@ -369,11 +334,7 @@ namespace mRemoteNG.Config.Putty { LoadSessionInfo(); } - if (!_sessionInfo.ContainsKey(setting)) - { - return string.Empty; - } - return _sessionInfo[setting]; + return !_sessionInfo.ContainsKey(setting) ? string.Empty : _sessionInfo[setting]; } } #endregion diff --git a/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs b/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs new file mode 100644 index 000000000..417eed3e0 --- /dev/null +++ b/mRemoteV1/Config/Serializers/ActiveDirectoryDeserializer.cs @@ -0,0 +1,88 @@ +using System; +using System.DirectoryServices; +using System.Text.RegularExpressions; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.Config.Serializers +{ + public class ActiveDirectoryDeserializer : IDeserializer + { + private readonly string _ldapPath; + + public ActiveDirectoryDeserializer(string ldapPath) + { + _ldapPath = ldapPath; + } + + public ConnectionTreeModel Deserialize() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + connectionTreeModel.AddRootNode(root); + + ImportContainers(_ldapPath, root); + + return connectionTreeModel; + } + + private void ImportContainers(string ldapPath, ContainerInfo parentContainer) + { + var match = Regex.Match(ldapPath, "ou=([^,]*)", RegexOptions.IgnoreCase); + var name = match.Success ? match.Groups[1].Captures[0].Value : Language.strActiveDirectory; + + var newContainer = new ContainerInfo {Name = name}; + parentContainer.AddChild(newContainer); + + ImportComputers(ldapPath, newContainer); + } + + private void ImportComputers(string ldapPath, ContainerInfo parentContainer) + { + try + { + const string ldapFilter = "(objectClass=computer)"; + using (var ldapSearcher = new DirectorySearcher()) + { + ldapSearcher.SearchRoot = new DirectoryEntry(ldapPath); + ldapSearcher.Filter = ldapFilter; + ldapSearcher.SearchScope = SearchScope.OneLevel; + ldapSearcher.PropertiesToLoad.AddRange(new[] { "securityEquals", "cn" }); + + var ldapResults = ldapSearcher.FindAll(); + foreach (SearchResult ldapResult in ldapResults) + { + using (var directoryEntry = ldapResult.GetDirectoryEntry()) + DeserializeConnection(directoryEntry, parentContainer); + } + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage("Config.Import.ActiveDirectory.ImportComputers() failed.", ex, logOnly: true); + } + } + + private void DeserializeConnection(DirectoryEntry directoryEntry, ContainerInfo parentContainer) + { + var displayName = Convert.ToString(directoryEntry.Properties["cn"].Value); + var description = Convert.ToString(directoryEntry.Properties["Description"].Value); + var hostName = Convert.ToString(directoryEntry.Properties["dNSHostName"].Value); + + var newConnectionInfo = new ConnectionInfo + { + Name = displayName, + Hostname = hostName, + Description = description + }; + newConnectionInfo.Inheritance.TurnOnInheritanceCompletely(); + newConnectionInfo.Inheritance.Description = false; + + parentContainer.AddChild(newConnectionInfo); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/CsvConnectionsSerializerMremotengFormat.cs b/mRemoteV1/Config/Serializers/CsvConnectionsSerializerMremotengFormat.cs new file mode 100644 index 000000000..9a4f36055 --- /dev/null +++ b/mRemoteV1/Config/Serializers/CsvConnectionsSerializerMremotengFormat.cs @@ -0,0 +1,141 @@ +using System; +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class CsvConnectionsSerializerMremotengFormat : ISerializer + { + private string _csv = ""; + + public Save SaveSecurity { get; set; } + + public string Serialize(ConnectionTreeModel connectionTreeModel) + { + var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); + return Serialize(rootNode); + } + + public string Serialize(ConnectionInfo serializationTarget) + { + _csv = ""; + WriteCsvHeader(); + SerializeNodesRecursive(serializationTarget); + return _csv; + } + + private void WriteCsvHeader() + { + var csvHeader = string.Empty; + csvHeader += "Name;Folder;Description;Icon;Panel;"; + if (SaveSecurity.Username) + csvHeader += "Username;"; + if (SaveSecurity.Password) + csvHeader += "Password;"; + if (SaveSecurity.Domain) + csvHeader += "Domain;"; + csvHeader += "Hostname;Protocol;PuttySession;Port;ConnectToConsole;UseCredSsp;RenderingEngine;ICAEncryptionStrength;RDPAuthenticationLevel;LoadBalanceInfo;Colors;Resolution;AutomaticResize;DisplayWallpaper;DisplayThemes;EnableFontSmoothing;EnableDesktopComposition;CacheBitmaps;RedirectDiskDrives;RedirectPorts;RedirectPrinters;RedirectSmartCards;RedirectSound;RedirectKeys;PreExtApp;PostExtApp;MacAddress;UserField;ExtApp;VNCCompression;VNCEncoding;VNCAuthMode;VNCProxyType;VNCProxyIP;VNCProxyPort;VNCProxyUsername;VNCProxyPassword;VNCColors;VNCSmartSizeMode;VNCViewOnly;RDGatewayUsageMethod;RDGatewayHostname;RDGatewayUseConnectionCredentials;RDGatewayUsername;RDGatewayPassword;RDGatewayDomain;"; + if (SaveSecurity.Inheritance) + csvHeader += "InheritCacheBitmaps;InheritColors;InheritDescription;InheritDisplayThemes;InheritDisplayWallpaper;InheritEnableFontSmoothing;InheritEnableDesktopComposition;InheritDomain;InheritIcon;InheritPanel;InheritPassword;InheritPort;InheritProtocol;InheritPuttySession;InheritRedirectDiskDrives;InheritRedirectKeys;InheritRedirectPorts;InheritRedirectPrinters;InheritRedirectSmartCards;InheritRedirectSound;InheritResolution;InheritAutomaticResize;InheritUseConsoleSession;InheritUseCredSsp;InheritRenderingEngine;InheritUsername;InheritICAEncryptionStrength;InheritRDPAuthenticationLevel;InheritLoadBalanceInfo;InheritPreExtApp;InheritPostExtApp;InheritMacAddress;InheritUserField;InheritExtApp;InheritVNCCompression;InheritVNCEncoding;InheritVNCAuthMode;InheritVNCProxyType;InheritVNCProxyIP;InheritVNCProxyPort;InheritVNCProxyUsername;InheritVNCProxyPassword;InheritVNCColors;InheritVNCSmartSizeMode;InheritVNCViewOnly;InheritRDGatewayUsageMethod;InheritRDGatewayHostname;InheritRDGatewayUseConnectionCredentials;InheritRDGatewayUsername;InheritRDGatewayPassword;InheritRDGatewayDomain"; + _csv += csvHeader; + } + + private void SerializeNodesRecursive(ConnectionInfo node) + { + var nodeAsContainer = node as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + if (child is ContainerInfo) + SerializeNodesRecursive((ContainerInfo) child); + else + SerializeConnectionInfo(child); + } + } + else + SerializeConnectionInfo(node); + } + + private void SerializeConnectionInfo(ConnectionInfo con) + { + var nodePath = con.TreeNode.FullPath; + + var firstSlash = nodePath.IndexOf("\\", StringComparison.Ordinal); + nodePath = nodePath.Remove(0, firstSlash + 1); + var lastSlash = nodePath.LastIndexOf("\\", StringComparison.Ordinal); + + nodePath = lastSlash > 0 ? nodePath.Remove(lastSlash) : ""; + + var csvLine = Environment.NewLine; + + csvLine += con.Name + ";" + nodePath + ";" + con.Description + ";" + con.Icon + ";" + con.Panel + ";"; + + if (SaveSecurity.Username) + csvLine += con.Username + ";"; + + if (SaveSecurity.Password) + csvLine += con.Password + ";"; + + if (SaveSecurity.Domain) + csvLine += con.Domain + ";"; + + csvLine += con.Hostname + ";" + con.Protocol + ";" + con.PuttySession + ";" + Convert.ToString(con.Port) + ";" + Convert.ToString(con.UseConsoleSession) + ";" + Convert.ToString(con.UseCredSsp) + ";" + con.RenderingEngine + ";" + con.ICAEncryptionStrength + ";" + con.RDPAuthenticationLevel + ";" + con.LoadBalanceInfo + ";" + con.Colors + ";" + con.Resolution + ";" + Convert.ToString(con.AutomaticResize) + ";" + Convert.ToString(con.DisplayWallpaper) + ";" + Convert.ToString(con.DisplayThemes) + ";" + Convert.ToString(con.EnableFontSmoothing) + ";" + Convert.ToString(con.EnableDesktopComposition) + ";" + Convert.ToString(con.CacheBitmaps) + ";" + Convert.ToString(con.RedirectDiskDrives) + ";" + Convert.ToString(con.RedirectPorts) + ";" + Convert.ToString(con.RedirectPrinters) + ";" + Convert.ToString(con.RedirectSmartCards) + ";" + con.RedirectSound + ";" + Convert.ToString(con.RedirectKeys) + ";" + con.PreExtApp + ";" + con.PostExtApp + ";" + con.MacAddress + ";" + con.UserField + ";" + con.ExtApp + ";" + con.VNCCompression + ";" + con.VNCEncoding + ";" + con.VNCAuthMode + ";" + con.VNCProxyType + ";" + con.VNCProxyIP + ";" + Convert.ToString(con.VNCProxyPort) + ";" + con.VNCProxyUsername + ";" + con.VNCProxyPassword + ";" + con.VNCColors + ";" + con.VNCSmartSizeMode + ";" + Convert.ToString(con.VNCViewOnly) + ";"; + + if (SaveSecurity.Inheritance) + { + csvLine += con.Inheritance.CacheBitmaps + ";" + + con.Inheritance.Colors + ";" + + con.Inheritance.Description + ";" + + con.Inheritance.DisplayThemes + ";" + + con.Inheritance.DisplayWallpaper + ";" + + con.Inheritance.EnableFontSmoothing + ";" + + con.Inheritance.EnableDesktopComposition + ";" + + con.Inheritance.Domain + ";" + + con.Inheritance.Icon + ";" + + con.Inheritance.Panel + ";" + + con.Inheritance.Password + ";" + + con.Inheritance.Port + ";" + + con.Inheritance.Protocol + ";" + + con.Inheritance.PuttySession + ";" + + con.Inheritance.RedirectDiskDrives + ";" + + con.Inheritance.RedirectKeys + ";" + + con.Inheritance.RedirectPorts + ";" + + con.Inheritance.RedirectPrinters + ";" + + con.Inheritance.RedirectSmartCards + ";" + + con.Inheritance.RedirectSound + ";" + + con.Inheritance.Resolution + ";" + + con.Inheritance.AutomaticResize + ";" + + con.Inheritance.UseConsoleSession + ";" + + con.Inheritance.UseCredSsp + ";" + + con.Inheritance.RenderingEngine + ";" + + con.Inheritance.Username + ";" + + con.Inheritance.ICAEncryptionStrength + ";" + + con.Inheritance.RDPAuthenticationLevel + ";" + + con.Inheritance.LoadBalanceInfo + ";" + + con.Inheritance.PreExtApp + ";" + + con.Inheritance.PostExtApp + ";" + + con.Inheritance.MacAddress + ";" + + con.Inheritance.UserField + ";" + + con.Inheritance.ExtApp + ";" + + con.Inheritance.VNCCompression + ";" + + con.Inheritance.VNCEncoding + ";" + + con.Inheritance.VNCAuthMode + ";" + + con.Inheritance.VNCProxyType + ";" + + con.Inheritance.VNCProxyIP + ";" + + con.Inheritance.VNCProxyPort + ";" + + con.Inheritance.VNCProxyUsername + ";" + + con.Inheritance.VNCProxyPassword + ";" + + con.Inheritance.VNCColors + ";" + + con.Inheritance.VNCSmartSizeMode + ";" + + con.Inheritance.VNCViewOnly; + } + + _csv += csvLine; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/CsvConnectionsSerializerRemoteDesktop2008Format.cs b/mRemoteV1/Config/Serializers/CsvConnectionsSerializerRemoteDesktop2008Format.cs new file mode 100644 index 000000000..471c11ca2 --- /dev/null +++ b/mRemoteV1/Config/Serializers/CsvConnectionsSerializerRemoteDesktop2008Format.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class CsvConnectionsSerializerRemoteDesktop2008Format : ISerializer + { + private string _csv = ""; + public Save SaveSecurity { get; set; } + + public string Serialize(ConnectionTreeModel connectionTreeModel) + { + var rootNode = connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); + return Serialize(rootNode); + } + + public string Serialize(ConnectionInfo serializationTarget) + { + _csv = ""; + SerializeNodesRecursive(serializationTarget); + return _csv; + } + + private void SerializeNodesRecursive(ConnectionInfo node) + { + var nodeAsContainer = node as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + if (child is ContainerInfo) + SerializeNodesRecursive((ContainerInfo)child); + else if (child.Protocol == ProtocolType.RDP) + SerializeConnectionInfo(child); + } + } + else if (node.Protocol == ProtocolType.RDP) + SerializeConnectionInfo(node); + } + + private void SerializeConnectionInfo(ConnectionInfo con) + { + var nodePath = con.TreeNode.FullPath; + + var firstSlash = nodePath.IndexOf("\\", StringComparison.Ordinal); + nodePath = nodePath.Remove(0, firstSlash + 1); + var lastSlash = nodePath.LastIndexOf("\\", StringComparison.Ordinal); + + nodePath = lastSlash > 0 ? nodePath.Remove(lastSlash) : ""; + + _csv += con.Name + ";" + con.Hostname + ";" + con.MacAddress + ";;" + con.Port + ";" + con.UseConsoleSession + ";" + nodePath + Environment.NewLine; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/DataTableDeserializer.cs b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs new file mode 100644 index 000000000..e9bceb437 --- /dev/null +++ b/mRemoteV1/Config/Serializers/DataTableDeserializer.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.Http; +using mRemoteNG.Connection.Protocol.ICA; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Connection.Protocol.VNC; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class DataTableDeserializer : IDeserializer + { + private readonly DataTable _dataTable; + + public DataTableDeserializer(DataTable dataTable) + { + _dataTable = dataTable; + } + + public DataTableDeserializer(IDataReader sqlDataReader) + { + _dataTable = new DataTable(); + _dataTable.Load(sqlDataReader); + } + + public ConnectionTreeModel Deserialize() + { + var connectionList = CreateNodesFromTable(); + var connectionTreeModel = CreateNodeHierarchy(connectionList); + return connectionTreeModel; + } + + private List CreateNodesFromTable() + { + var nodeList = new List(); + foreach (DataRow row in _dataTable.Rows) + { + if ((string)row["Type"] == "Connection") + nodeList.Add(DeserializeConnectionInfo(row)); + else if ((string)row["Type"] == "Container") + nodeList.Add(DeserializeContainerInfo(row)); + } + return nodeList; + } + + private ConnectionInfo DeserializeConnectionInfo(DataRow row) + { + var connectionInfo = new ConnectionInfo(); + PopulateConnectionInfoFromDatarow(row, connectionInfo); + return connectionInfo; + } + + private ContainerInfo DeserializeContainerInfo(DataRow row) + { + var containerInfo = new ContainerInfo(); + PopulateConnectionInfoFromDatarow(row, containerInfo); + return containerInfo; + } + + private void PopulateConnectionInfoFromDatarow(DataRow dataRow, ConnectionInfo connectionInfo) + { + connectionInfo.Name = (string)dataRow["Name"]; + connectionInfo.ConstantID = (string)dataRow["ConstantID"]; + //connectionInfo.Parent.ConstantID = (string)dataRow["ParentID"]; + //connectionInfo is ContainerInfo ? ((ContainerInfo)connectionInfo).IsExpanded.ToString() : "" = dataRow["Expanded"]; + connectionInfo.Description = (string)dataRow["Description"]; + connectionInfo.Icon = (string)dataRow["Icon"]; + connectionInfo.Panel = (string)dataRow["Panel"]; + connectionInfo.Username = (string)dataRow["Username"]; + connectionInfo.Domain = (string)dataRow["DomainName"]; + connectionInfo.Password = (string)dataRow["Password"]; + connectionInfo.Hostname = (string)dataRow["Hostname"]; + connectionInfo.Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), (string)dataRow["Protocol"]); + connectionInfo.PuttySession = (string)dataRow["PuttySession"]; + connectionInfo.Port = (int)dataRow["Port"]; + connectionInfo.UseConsoleSession = (bool)dataRow["ConnectToConsole"]; + connectionInfo.UseCredSsp = (bool)dataRow["UseCredSsp"]; + connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), (string)dataRow["RenderingEngine"]); + connectionInfo.ICAEncryptionStrength = (ProtocolICA.EncryptionStrength)Enum.Parse(typeof(ProtocolICA.EncryptionStrength), (string)dataRow["ICAEncryptionStrength"]); + connectionInfo.RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel)Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), (string)dataRow["RDPAuthenticationLevel"]); + connectionInfo.LoadBalanceInfo = (string)dataRow["LoadBalanceInfo"]; + connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors) ,(string)dataRow["Colors"]); + connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), (string)dataRow["Resolution"]); + connectionInfo.AutomaticResize = (bool)dataRow["AutomaticResize"]; + connectionInfo.DisplayWallpaper = (bool)dataRow["DisplayWallpaper"]; + connectionInfo.DisplayThemes = (bool)dataRow["DisplayThemes"]; + connectionInfo.EnableFontSmoothing = (bool)dataRow["EnableFontSmoothing"]; + connectionInfo.EnableDesktopComposition = (bool)dataRow["EnableDesktopComposition"]; + connectionInfo.CacheBitmaps = (bool)dataRow["CacheBitmaps"]; + connectionInfo.RedirectDiskDrives = (bool)dataRow["RedirectDiskDrives"]; + connectionInfo.RedirectPorts = (bool)dataRow["RedirectPorts"]; + connectionInfo.RedirectPrinters = (bool)dataRow["RedirectPrinters"]; + connectionInfo.RedirectSmartCards = (bool)dataRow["RedirectSmartCards"]; + connectionInfo.RedirectSound = (ProtocolRDP.RDPSounds)Enum.Parse(typeof(ProtocolRDP.RDPSounds), (string)dataRow["RedirectSound"]); + connectionInfo.RedirectKeys = (bool)dataRow["RedirectKeys"]; + connectionInfo.PleaseConnect = (bool)dataRow["Connected"]; + connectionInfo.PreExtApp = (string)dataRow["PreExtApp"]; + connectionInfo.PostExtApp = (string)dataRow["PostExtApp"]; + connectionInfo.MacAddress = (string)dataRow["MacAddress"]; + connectionInfo.UserField = (string)dataRow["UserField"]; + connectionInfo.ExtApp = (string)dataRow["ExtApp"]; + connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression), (string)dataRow["VNCCompression"]); + connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding) ,(string)dataRow["VNCEncoding"]); + connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), (string)dataRow["VNCAuthMode"]); + connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), (string)dataRow["VNCProxyType"]); + connectionInfo.VNCProxyIP = (string)dataRow["VNCProxyIP"]; + connectionInfo.VNCProxyPort = (int)dataRow["VNCProxyPort"]; + connectionInfo.VNCProxyUsername = (string)dataRow["VNCProxyUsername"]; + connectionInfo.VNCProxyPassword = (string)dataRow["VNCProxyPassword"]; + connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), (string)dataRow["VNCColors"]); + connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), (string)dataRow["VNCSmartSizeMode"]); + connectionInfo.VNCViewOnly = (bool)dataRow["VNCViewOnly"]; + connectionInfo.RDGatewayUsageMethod = (ProtocolRDP.RDGatewayUsageMethod)Enum.Parse(typeof(ProtocolRDP.RDGatewayUsageMethod), (string)dataRow["RDGatewayUsageMethod"]); + connectionInfo.RDGatewayHostname = (string)dataRow["RDGatewayHostname"]; + connectionInfo.RDGatewayUseConnectionCredentials = (ProtocolRDP.RDGatewayUseConnectionCredentials)Enum.Parse(typeof(ProtocolRDP.RDGatewayUseConnectionCredentials), (string)dataRow["RDGatewayUseConnectionCredentials"]); + connectionInfo.RDGatewayUsername = (string)dataRow["RDGatewayUsername"]; + connectionInfo.RDGatewayPassword = (string)dataRow["RDGatewayPassword"]; + connectionInfo.RDGatewayDomain = (string)dataRow["RDGatewayDomain"]; + + connectionInfo.Inheritance.CacheBitmaps = (bool)dataRow["InheritCacheBitmaps"]; + connectionInfo.Inheritance.Colors = (bool)dataRow["InheritColors"]; + connectionInfo.Inheritance.Description = (bool)dataRow["InheritDescription"]; + connectionInfo.Inheritance.DisplayThemes = (bool)dataRow["InheritDisplayThemes"]; + connectionInfo.Inheritance.DisplayWallpaper = (bool)dataRow["InheritDisplayWallpaper"]; + connectionInfo.Inheritance.EnableFontSmoothing = (bool)dataRow["InheritEnableFontSmoothing"]; + connectionInfo.Inheritance.EnableDesktopComposition = (bool)dataRow["InheritEnableDesktopComposition"]; + connectionInfo.Inheritance.Domain = (bool)dataRow["InheritDomain"]; + connectionInfo.Inheritance.Icon = (bool)dataRow["InheritIcon"]; + connectionInfo.Inheritance.Panel = (bool)dataRow["InheritPanel"]; + connectionInfo.Inheritance.Password = (bool)dataRow["InheritPassword"]; + connectionInfo.Inheritance.Port = (bool)dataRow["InheritPort"]; + connectionInfo.Inheritance.Protocol = (bool)dataRow["InheritProtocol"]; + connectionInfo.Inheritance.PuttySession = (bool)dataRow["InheritPuttySession"]; + connectionInfo.Inheritance.RedirectDiskDrives = (bool)dataRow["InheritRedirectDiskDrives"]; + connectionInfo.Inheritance.RedirectKeys = (bool)dataRow["InheritRedirectKeys"]; + connectionInfo.Inheritance.RedirectPorts = (bool)dataRow["InheritRedirectPorts"]; + connectionInfo.Inheritance.RedirectPrinters = (bool)dataRow["InheritRedirectPrinters"]; + connectionInfo.Inheritance.RedirectSmartCards = (bool)dataRow["InheritRedirectSmartCards"]; + connectionInfo.Inheritance.RedirectSound = (bool)dataRow["InheritRedirectSound"]; + connectionInfo.Inheritance.Resolution = (bool)dataRow["InheritResolution"]; + connectionInfo.Inheritance.AutomaticResize = (bool)dataRow["InheritAutomaticResize"]; + connectionInfo.Inheritance.UseConsoleSession = (bool)dataRow["InheritUseConsoleSession"]; + connectionInfo.Inheritance.UseCredSsp = (bool)dataRow["InheritUseCredSsp"]; + connectionInfo.Inheritance.RenderingEngine = (bool)dataRow["InheritRenderingEngine"]; + connectionInfo.Inheritance.Username = (bool)dataRow["InheritUsername"]; + connectionInfo.Inheritance.ICAEncryptionStrength = (bool)dataRow["InheritICAEncryptionStrength"]; + connectionInfo.Inheritance.RDPAuthenticationLevel = (bool)dataRow["InheritRDPAuthenticationLevel"]; + connectionInfo.Inheritance.LoadBalanceInfo = (bool)dataRow["InheritLoadBalanceInfo"]; + connectionInfo.Inheritance.PreExtApp = (bool)dataRow["InheritPreExtApp"]; + connectionInfo.Inheritance.PostExtApp = (bool)dataRow["InheritPostExtApp"]; + connectionInfo.Inheritance.MacAddress = (bool)dataRow["InheritMacAddress"]; + connectionInfo.Inheritance.UserField = (bool)dataRow["InheritUserField"]; + connectionInfo.Inheritance.ExtApp = (bool)dataRow["InheritExtApp"]; + connectionInfo.Inheritance.VNCCompression = (bool)dataRow["InheritVNCCompression"]; + connectionInfo.Inheritance.VNCEncoding = (bool)dataRow["InheritVNCEncoding"]; + connectionInfo.Inheritance.VNCAuthMode = (bool)dataRow["InheritVNCAuthMode"]; + connectionInfo.Inheritance.VNCProxyType = (bool)dataRow["InheritVNCProxyType"]; + connectionInfo.Inheritance.VNCProxyIP = (bool)dataRow["InheritVNCProxyIP"]; + connectionInfo.Inheritance.VNCProxyPort = (bool)dataRow["InheritVNCProxyPort"]; + connectionInfo.Inheritance.VNCProxyUsername = (bool)dataRow["InheritVNCProxyUsername"]; + connectionInfo.Inheritance.VNCProxyPassword = (bool)dataRow["InheritVNCProxyPassword"]; + connectionInfo.Inheritance.VNCColors = (bool)dataRow["InheritVNCColors"]; + connectionInfo.Inheritance.VNCSmartSizeMode = (bool)dataRow["InheritVNCSmartSizeMode"]; + connectionInfo.Inheritance.VNCViewOnly = (bool)dataRow["InheritVNCViewOnly"]; + connectionInfo.Inheritance.RDGatewayUsageMethod = (bool)dataRow["InheritRDGatewayUsageMethod"]; + connectionInfo.Inheritance.RDGatewayHostname = (bool)dataRow["InheritRDGatewayHostname"]; + connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = (bool)dataRow["InheritRDGatewayUseConnectionCredentials"]; + connectionInfo.Inheritance.RDGatewayUsername = (bool)dataRow["InheritRDGatewayUsername"]; + connectionInfo.Inheritance.RDGatewayPassword = (bool)dataRow["InheritRDGatewayPassword"]; + connectionInfo.Inheritance.RDGatewayDomain = (bool)dataRow["InheritRDGatewayDomain"]; + } + + private ConnectionTreeModel CreateNodeHierarchy(List connectionList) + { + var connectionTreeModel = new ConnectionTreeModel(); + var rootNode = new RootNodeInfo(RootNodeType.Connection) {ConstantID = "0"}; + connectionTreeModel.AddRootNode(rootNode); + + foreach (DataRow row in _dataTable.Rows) + { + var id = (string) row["ConstantID"]; + var connectionInfo = connectionList.First(node => node.ConstantID == id); + var parentId = (string) row["ParentID"]; + if (parentId == "0") + rootNode.AddChild(connectionInfo); + else + (connectionList.First(node => node.ConstantID == parentId) as ContainerInfo)?.AddChild(connectionInfo); + } + return connectionTreeModel; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/DataTableSerializer.cs new file mode 100644 index 000000000..f69f5cb82 --- /dev/null +++ b/mRemoteV1/Config/Serializers/DataTableSerializer.cs @@ -0,0 +1,350 @@ +using System; +using System.Data; +using System.Data.SqlTypes; +using System.Linq; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class DataTableSerializer : ISerializer + { + private DataTable _dataTable; + private const string TableName = "tblCons"; + private readonly Save _saveSecurity; + private int _currentNodeIndex; + + public DataTableSerializer(Save saveSecurity) + { + _saveSecurity = saveSecurity; + } + + + public DataTable Serialize(ConnectionTreeModel connectionTreeModel) + { + var rootNode = (RootNodeInfo)connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); + return Serialize(rootNode); + } + + public DataTable Serialize(ConnectionInfo serializationTarget) + { + _dataTable = new DataTable(TableName); + CreateSchema(); + SetPrimaryKey(); + _currentNodeIndex = 0; + SerializeNodesRecursive(serializationTarget); + return _dataTable; + } + + private void CreateSchema() + { + _dataTable.Columns.Add("ID", typeof(int)); + _dataTable.Columns[0].AutoIncrement = true; + _dataTable.Columns.Add("ConstantID", typeof(string)); + _dataTable.Columns.Add("PositionID", typeof(int)); + _dataTable.Columns.Add("ParentID", typeof(string)); + _dataTable.Columns.Add("LastChange", typeof(SqlDateTime)); + _dataTable.Columns.Add("Name", typeof(string)); + _dataTable.Columns.Add("Type", typeof(string)); + _dataTable.Columns.Add("Expanded", typeof(bool)); + _dataTable.Columns.Add("Description", typeof(string)); + _dataTable.Columns.Add("Icon", typeof(string)); + _dataTable.Columns.Add("Panel", typeof(string)); + _dataTable.Columns.Add("Username", typeof(string)); + _dataTable.Columns.Add("DomainName", typeof(string)); + _dataTable.Columns.Add("Password", typeof(string)); + _dataTable.Columns.Add("Hostname", typeof(string)); + _dataTable.Columns.Add("Protocol", typeof(string)); + _dataTable.Columns.Add("PuttySession", typeof(string)); + _dataTable.Columns.Add("Port", typeof(int)); + _dataTable.Columns.Add("ConnectToConsole", typeof(bool)); + _dataTable.Columns.Add("UseCredSsp", typeof(bool)); + _dataTable.Columns.Add("RenderingEngine", typeof(string)); + _dataTable.Columns.Add("ICAEncryptionStrength", typeof(string)); + _dataTable.Columns.Add("RDPAuthenticationLevel", typeof(string)); + _dataTable.Columns.Add("Colors", typeof(string)); + _dataTable.Columns.Add("Resolution", typeof(string)); + _dataTable.Columns.Add("DisplayWallpaper", typeof(bool)); + _dataTable.Columns.Add("DisplayThemes", typeof(bool)); + _dataTable.Columns.Add("EnableFontSmoothing", typeof(bool)); + _dataTable.Columns.Add("EnableDesktopComposition", typeof(bool)); + _dataTable.Columns.Add("CacheBitmaps", typeof(bool)); + _dataTable.Columns.Add("RedirectDiskDrives", typeof(bool)); + _dataTable.Columns.Add("RedirectPorts", typeof(bool)); + _dataTable.Columns.Add("RedirectPrinters", typeof(bool)); + _dataTable.Columns.Add("RedirectSmartCards", typeof(bool)); + _dataTable.Columns.Add("RedirectSound", typeof(string)); + _dataTable.Columns.Add("RedirectKeys", typeof(bool)); + _dataTable.Columns.Add("Connected", typeof(bool)); + _dataTable.Columns.Add("PreExtApp", typeof(string)); + _dataTable.Columns.Add("PostExtApp", typeof(string)); + _dataTable.Columns.Add("MacAddress", typeof(string)); + _dataTable.Columns.Add("UserField", typeof(string)); + _dataTable.Columns.Add("ExtApp", typeof(string)); + _dataTable.Columns.Add("VNCCompression", typeof(string)); + _dataTable.Columns.Add("VNCEncoding", typeof(string)); + _dataTable.Columns.Add("VNCAuthMode", typeof(string)); + _dataTable.Columns.Add("VNCProxyType", typeof(string)); + _dataTable.Columns.Add("VNCProxyIP", typeof(string)); + _dataTable.Columns.Add("VNCProxyPort", typeof(int)); + _dataTable.Columns.Add("VNCProxyUsername", typeof(string)); + _dataTable.Columns.Add("VNCProxyPassword", typeof(string)); + _dataTable.Columns.Add("VNCColors", typeof(string)); + _dataTable.Columns.Add("VNCSmartSizeMode", typeof(string)); + _dataTable.Columns.Add("VNCViewOnly", typeof(bool)); + _dataTable.Columns.Add("RDGatewayUsageMethod", typeof(string)); + _dataTable.Columns.Add("RDGatewayHostname", typeof(string)); + _dataTable.Columns.Add("RDGatewayUseConnectionCredentials", typeof(string)); + _dataTable.Columns.Add("RDGatewayUsername", typeof(string)); + _dataTable.Columns.Add("RDGatewayPassword", typeof(string)); + _dataTable.Columns.Add("RDGatewayDomain", typeof(string)); + _dataTable.Columns.Add("InheritCacheBitmaps", typeof(bool)); + _dataTable.Columns.Add("InheritColors", typeof(bool)); + _dataTable.Columns.Add("InheritDescription", typeof(bool)); + _dataTable.Columns.Add("InheritDisplayThemes", typeof(bool)); + _dataTable.Columns.Add("InheritDisplayWallpaper", typeof(bool)); + _dataTable.Columns.Add("InheritEnableFontSmoothing", typeof(bool)); + _dataTable.Columns.Add("InheritEnableDesktopComposition", typeof(bool)); + _dataTable.Columns.Add("InheritDomain", typeof(bool)); + _dataTable.Columns.Add("InheritIcon", typeof(bool)); + _dataTable.Columns.Add("InheritPanel", typeof(bool)); + _dataTable.Columns.Add("InheritPassword", typeof(bool)); + _dataTable.Columns.Add("InheritPort", typeof(bool)); + _dataTable.Columns.Add("InheritProtocol", typeof(bool)); + _dataTable.Columns.Add("InheritPuttySession", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectDiskDrives", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectKeys", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectPorts", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectPrinters", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectSmartCards", typeof(bool)); + _dataTable.Columns.Add("InheritRedirectSound", typeof(bool)); + _dataTable.Columns.Add("InheritResolution", typeof(bool)); + _dataTable.Columns.Add("InheritUseConsoleSession", typeof(bool)); + _dataTable.Columns.Add("InheritUseCredSsp", typeof(bool)); + _dataTable.Columns.Add("InheritRenderingEngine", typeof(bool)); + _dataTable.Columns.Add("InheritICAEncryptionStrength", typeof(bool)); + _dataTable.Columns.Add("InheritRDPAuthenticationLevel", typeof(bool)); + _dataTable.Columns.Add("InheritUsername", typeof(bool)); + _dataTable.Columns.Add("InheritPreExtApp", typeof(bool)); + _dataTable.Columns.Add("InheritPostExtApp", typeof(bool)); + _dataTable.Columns.Add("InheritMacAddress", typeof(bool)); + _dataTable.Columns.Add("InheritUserField", typeof(bool)); + _dataTable.Columns.Add("InheritExtApp", typeof(bool)); + _dataTable.Columns.Add("InheritVNCCompression", typeof(bool)); + _dataTable.Columns.Add("InheritVNCEncoding", typeof(bool)); + _dataTable.Columns.Add("InheritVNCAuthMode", typeof(bool)); + _dataTable.Columns.Add("InheritVNCProxyType", typeof(bool)); + _dataTable.Columns.Add("InheritVNCProxyIP", typeof(bool)); + _dataTable.Columns.Add("InheritVNCProxyPort", typeof(bool)); + _dataTable.Columns.Add("InheritVNCProxyUsername", typeof(bool)); + _dataTable.Columns.Add("InheritVNCProxyPassword", typeof(bool)); + _dataTable.Columns.Add("InheritVNCColors", typeof(bool)); + _dataTable.Columns.Add("InheritVNCSmartSizeMode", typeof(bool)); + _dataTable.Columns.Add("InheritVNCViewOnly", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayUsageMethod", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayHostname", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayUseConnectionCredentials", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayUsername", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayPassword", typeof(bool)); + _dataTable.Columns.Add("InheritRDGatewayDomain", typeof(bool)); + _dataTable.Columns.Add("LoadBalanceInfo", typeof(string)); + _dataTable.Columns.Add("AutomaticResize", typeof(bool)); + _dataTable.Columns.Add("InheritLoadBalanceInfo", typeof(bool)); + _dataTable.Columns.Add("InheritAutomaticResize", typeof(bool)); + } + + private void SetPrimaryKey() + { + _dataTable.PrimaryKey = new[] { _dataTable.Columns["ConstantID"] }; + } + + private void SerializeNodesRecursive(ConnectionInfo connectionInfo) + { + if (!(connectionInfo is RootNodeInfo)) + SerializeConnectionInfo(connectionInfo); + var containerInfo = connectionInfo as ContainerInfo; + if (containerInfo == null) return; + foreach (var child in containerInfo.Children) + SerializeNodesRecursive(child); + } + + private void SerializeConnectionInfo(ConnectionInfo connectionInfo) + { + _currentNodeIndex++; + var dataRow = _dataTable.NewRow(); + dataRow["ID"] = DBNull.Value; + dataRow["Name"] = connectionInfo.Name; + dataRow["Type"] = connectionInfo.GetTreeNodeType().ToString(); + dataRow["ConstantID"] = connectionInfo.ConstantID; + dataRow["ParentID"] = connectionInfo.Parent.ConstantID; + dataRow["PositionID"] = _currentNodeIndex; + dataRow["LastChange"] = (SqlDateTime)DateTime.Now; + dataRow["Expanded"] = connectionInfo is ContainerInfo ? ((ContainerInfo)connectionInfo).IsExpanded : false; + dataRow["Description"] = connectionInfo.Description; + dataRow["Icon"] = connectionInfo.Icon; + dataRow["Panel"] = connectionInfo.Panel; + dataRow["Username"] = _saveSecurity.Username ? connectionInfo.Username : ""; + dataRow["DomainName"] = _saveSecurity.Domain ? connectionInfo.Domain : ""; + dataRow["Password"] = _saveSecurity.Password ? connectionInfo.Password : ""; + dataRow["Hostname"] = connectionInfo.Hostname; + dataRow["Protocol"] = connectionInfo.Protocol; + dataRow["PuttySession"] = connectionInfo.PuttySession; + dataRow["Port"] = connectionInfo.Port; + dataRow["ConnectToConsole"] = connectionInfo.UseConsoleSession; + dataRow["UseCredSsp"] = connectionInfo.UseCredSsp; + dataRow["RenderingEngine"] = connectionInfo.RenderingEngine; + dataRow["ICAEncryptionStrength"] = connectionInfo.ICAEncryptionStrength; + dataRow["RDPAuthenticationLevel"] = connectionInfo.RDPAuthenticationLevel; + dataRow["LoadBalanceInfo"] = connectionInfo.LoadBalanceInfo; + dataRow["Colors"] = connectionInfo.Colors; + dataRow["Resolution"] = connectionInfo.Resolution; + dataRow["AutomaticResize"] = connectionInfo.AutomaticResize; + dataRow["DisplayWallpaper"] = connectionInfo.DisplayWallpaper; + dataRow["DisplayThemes"] = connectionInfo.DisplayThemes; + dataRow["EnableFontSmoothing"] = connectionInfo.EnableFontSmoothing; + dataRow["EnableDesktopComposition"] = connectionInfo.EnableDesktopComposition; + dataRow["CacheBitmaps"] = connectionInfo.CacheBitmaps; + dataRow["RedirectDiskDrives"] = connectionInfo.RedirectDiskDrives; + dataRow["RedirectPorts"] = connectionInfo.RedirectPorts; + dataRow["RedirectPrinters"] = connectionInfo.RedirectPrinters; + dataRow["RedirectSmartCards"] = connectionInfo.RedirectSmartCards; + dataRow["RedirectSound"] = connectionInfo.RedirectSound; + dataRow["RedirectKeys"] = connectionInfo.RedirectKeys; + dataRow["Connected"] = connectionInfo.OpenConnections.Count > 0; + dataRow["PreExtApp"] = connectionInfo.PreExtApp; + dataRow["PostExtApp"] = connectionInfo.PostExtApp; + dataRow["MacAddress"] = connectionInfo.MacAddress; + dataRow["UserField"] = connectionInfo.UserField; + dataRow["ExtApp"] = connectionInfo.ExtApp; + dataRow["VNCCompression"] = connectionInfo.VNCCompression; + dataRow["VNCEncoding"] = connectionInfo.VNCEncoding; + dataRow["VNCAuthMode"] = connectionInfo.VNCAuthMode; + dataRow["VNCProxyType"] = connectionInfo.VNCProxyType; + dataRow["VNCProxyIP"] = connectionInfo.VNCProxyIP; + dataRow["VNCProxyPort"] = connectionInfo.VNCProxyPort; + dataRow["VNCProxyUsername"] = connectionInfo.VNCProxyUsername; + dataRow["VNCProxyPassword"] = connectionInfo.VNCProxyPassword; + dataRow["VNCColors"] = connectionInfo.VNCColors; + dataRow["VNCSmartSizeMode"] = connectionInfo.VNCSmartSizeMode; + dataRow["VNCViewOnly"] = connectionInfo.VNCViewOnly; + dataRow["RDGatewayUsageMethod"] = connectionInfo.RDGatewayUsageMethod; + dataRow["RDGatewayHostname"] = connectionInfo.RDGatewayHostname; + dataRow["RDGatewayUseConnectionCredentials"] = connectionInfo.RDGatewayUseConnectionCredentials; + dataRow["RDGatewayUsername"] = connectionInfo.RDGatewayUsername; + dataRow["RDGatewayPassword"] = connectionInfo.RDGatewayPassword; + dataRow["RDGatewayDomain"] = connectionInfo.RDGatewayDomain; + if (_saveSecurity.Inheritance) + { + dataRow["InheritCacheBitmaps"] = connectionInfo.Inheritance.CacheBitmaps; + dataRow["InheritColors"] = connectionInfo.Inheritance.Colors; + dataRow["InheritDescription"] = connectionInfo.Inheritance.Description; + dataRow["InheritDisplayThemes"] = connectionInfo.Inheritance.DisplayThemes; + dataRow["InheritDisplayWallpaper"] = connectionInfo.Inheritance.DisplayWallpaper; + dataRow["InheritEnableFontSmoothing"] = connectionInfo.Inheritance.EnableFontSmoothing; + dataRow["InheritEnableDesktopComposition"] = connectionInfo.Inheritance.EnableDesktopComposition; + dataRow["InheritDomain"] = connectionInfo.Inheritance.Domain; + dataRow["InheritIcon"] = connectionInfo.Inheritance.Icon; + dataRow["InheritPanel"] = connectionInfo.Inheritance.Panel; + dataRow["InheritPassword"] = connectionInfo.Inheritance.Password; + dataRow["InheritPort"] = connectionInfo.Inheritance.Port; + dataRow["InheritProtocol"] = connectionInfo.Inheritance.Protocol; + dataRow["InheritPuttySession"] = connectionInfo.Inheritance.PuttySession; + dataRow["InheritRedirectDiskDrives"] = connectionInfo.Inheritance.RedirectDiskDrives; + dataRow["InheritRedirectKeys"] = connectionInfo.Inheritance.RedirectKeys; + dataRow["InheritRedirectPorts"] = connectionInfo.Inheritance.RedirectPorts; + dataRow["InheritRedirectPrinters"] = connectionInfo.Inheritance.RedirectPrinters; + dataRow["InheritRedirectSmartCards"] = connectionInfo.Inheritance.RedirectSmartCards; + dataRow["InheritRedirectSound"] = connectionInfo.Inheritance.RedirectSound; + dataRow["InheritResolution"] = connectionInfo.Inheritance.Resolution; + dataRow["InheritAutomaticResize"] = connectionInfo.Inheritance.AutomaticResize; + dataRow["InheritUseConsoleSession"] = connectionInfo.Inheritance.UseConsoleSession; + dataRow["InheritUseCredSsp"] = connectionInfo.Inheritance.UseCredSsp; + dataRow["InheritRenderingEngine"] = connectionInfo.Inheritance.RenderingEngine; + dataRow["InheritUsername"] = connectionInfo.Inheritance.Username; + dataRow["InheritICAEncryptionStrength"] = connectionInfo.Inheritance.ICAEncryptionStrength; + dataRow["InheritRDPAuthenticationLevel"] = connectionInfo.Inheritance.RDPAuthenticationLevel; + dataRow["InheritLoadBalanceInfo"] = connectionInfo.Inheritance.LoadBalanceInfo; + dataRow["InheritPreExtApp"] = connectionInfo.Inheritance.PreExtApp; + dataRow["InheritPostExtApp"] = connectionInfo.Inheritance.PostExtApp; + dataRow["InheritMacAddress"] = connectionInfo.Inheritance.MacAddress; + dataRow["InheritUserField"] = connectionInfo.Inheritance.UserField; + dataRow["InheritExtApp"] = connectionInfo.Inheritance.ExtApp; + dataRow["InheritVNCCompression"] = connectionInfo.Inheritance.VNCCompression; + dataRow["InheritVNCEncoding"] = connectionInfo.Inheritance.VNCEncoding; + dataRow["InheritVNCAuthMode"] = connectionInfo.Inheritance.VNCAuthMode; + dataRow["InheritVNCProxyType"] = connectionInfo.Inheritance.VNCProxyType; + dataRow["InheritVNCProxyIP"] = connectionInfo.Inheritance.VNCProxyIP; + dataRow["InheritVNCProxyPort"] = connectionInfo.Inheritance.VNCProxyPort; + dataRow["InheritVNCProxyUsername"] = connectionInfo.Inheritance.VNCProxyUsername; + dataRow["InheritVNCProxyPassword"] = connectionInfo.Inheritance.VNCProxyPassword; + dataRow["InheritVNCColors"] = connectionInfo.Inheritance.VNCColors; + dataRow["InheritVNCSmartSizeMode"] = connectionInfo.Inheritance.VNCSmartSizeMode; + dataRow["InheritVNCViewOnly"] = connectionInfo.Inheritance.VNCViewOnly; + dataRow["InheritRDGatewayUsageMethod"] = connectionInfo.Inheritance.RDGatewayUsageMethod; + dataRow["InheritRDGatewayHostname"] = connectionInfo.Inheritance.RDGatewayHostname; + dataRow["InheritRDGatewayUseConnectionCredentials"] = connectionInfo.Inheritance.RDGatewayUseConnectionCredentials; + dataRow["InheritRDGatewayUsername"] = connectionInfo.Inheritance.RDGatewayUsername; + dataRow["InheritRDGatewayPassword"] = connectionInfo.Inheritance.RDGatewayPassword; + dataRow["InheritRDGatewayDomain"] = connectionInfo.Inheritance.RDGatewayDomain; + } + else + { + dataRow["InheritCacheBitmaps"] = false; + dataRow["InheritColors"] = false; + dataRow["InheritDescription"] = false; + dataRow["InheritDisplayThemes"] = false; + dataRow["InheritDisplayWallpaper"] = false; + dataRow["InheritEnableFontSmoothing"] = false; + dataRow["InheritEnableDesktopComposition"] = false; + dataRow["InheritDomain"] = false; + dataRow["InheritIcon"] = false; + dataRow["InheritPanel"] = false; + dataRow["InheritPassword"] = false; + dataRow["InheritPort"] = false; + dataRow["InheritProtocol"] = false; + dataRow["InheritPuttySession"] = false; + dataRow["InheritRedirectDiskDrives"] = false; + dataRow["InheritRedirectKeys"] = false; + dataRow["InheritRedirectPorts"] = false; + dataRow["InheritRedirectPrinters"] = false; + dataRow["InheritRedirectSmartCards"] = false; + dataRow["InheritRedirectSound"] = false; + dataRow["InheritResolution"] = false; + dataRow["InheritAutomaticResize"] = false; + dataRow["InheritUseConsoleSession"] = false; + dataRow["InheritUseCredSsp"] = false; + dataRow["InheritRenderingEngine"] = false; + dataRow["InheritUsername"] = false; + dataRow["InheritICAEncryptionStrength"] = false; + dataRow["InheritRDPAuthenticationLevel"] = false; + dataRow["InheritLoadBalanceInfo"] = false; + dataRow["InheritPreExtApp"] = false; + dataRow["InheritPostExtApp"] = false; + dataRow["InheritMacAddress"] = false; + dataRow["InheritUserField"] = false; + dataRow["InheritExtApp"] = false; + dataRow["InheritVNCCompression"] = false; + dataRow["InheritVNCEncoding"] = false; + dataRow["InheritVNCAuthMode"] = false; + dataRow["InheritVNCProxyType"] = false; + dataRow["InheritVNCProxyIP"] = false; + dataRow["InheritVNCProxyPort"] = false; + dataRow["InheritVNCProxyUsername"] = false; + dataRow["InheritVNCProxyPassword"] = false; + dataRow["InheritVNCColors"] = false; + dataRow["InheritVNCSmartSizeMode"] = false; + dataRow["InheritVNCViewOnly"] = false; + dataRow["InheritRDGatewayUsageMethod"] = false; + dataRow["InheritRDGatewayHostname"] = false; + dataRow["InheritRDGatewayUseConnectionCredentials"] = false; + dataRow["InheritRDGatewayUsername"] = false; + dataRow["InheritRDGatewayPassword"] = false; + dataRow["InheritRDGatewayDomain"] = false; + } + _dataTable.Rows.Add(dataRow); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/IDeserializer.cs b/mRemoteV1/Config/Serializers/IDeserializer.cs new file mode 100644 index 000000000..4ba89abfd --- /dev/null +++ b/mRemoteV1/Config/Serializers/IDeserializer.cs @@ -0,0 +1,9 @@ +using mRemoteNG.Tree; + +namespace mRemoteNG.Config.Serializers +{ + public interface IDeserializer + { + ConnectionTreeModel Deserialize(); + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/ISerializer.cs b/mRemoteV1/Config/Serializers/ISerializer.cs new file mode 100644 index 000000000..116ec562b --- /dev/null +++ b/mRemoteV1/Config/Serializers/ISerializer.cs @@ -0,0 +1,12 @@ +using mRemoteNG.Connection; +using mRemoteNG.Tree; + +namespace mRemoteNG.Config.Serializers +{ + public interface ISerializer + { + TFormat Serialize(ConnectionTreeModel connectionTreeModel); + + TFormat Serialize(ConnectionInfo serializationTarget); + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/PortScanDeserializer.cs b/mRemoteV1/Config/Serializers/PortScanDeserializer.cs new file mode 100644 index 000000000..86cd89aae --- /dev/null +++ b/mRemoteV1/Config/Serializers/PortScanDeserializer.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNG.Tools; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.Config.Serializers +{ + public class PortScanDeserializer : IDeserializer + { + private readonly IEnumerable _scannedHosts; + private readonly ProtocolType _targetProtocolType; + + public PortScanDeserializer(IEnumerable scannedHosts, ProtocolType targetProtocolType) + { + _scannedHosts = scannedHosts; + _targetProtocolType = targetProtocolType; + } + + public ConnectionTreeModel Deserialize() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + connectionTreeModel.AddRootNode(root); + + foreach (var host in _scannedHosts) + ImportScannedHost(host, root); + + return connectionTreeModel; + } + + private void ImportScannedHost(ScanHost host, ContainerInfo parentContainer) + { + var finalProtocol = default(ProtocolType); + var protocolValid = true; + + switch (_targetProtocolType) + { + case ProtocolType.SSH2: + if (host.SSH) + finalProtocol = ProtocolType.SSH2; + break; + case ProtocolType.Telnet: + if (host.Telnet) + finalProtocol = ProtocolType.Telnet; + break; + case ProtocolType.HTTP: + if (host.HTTP) + finalProtocol = ProtocolType.HTTP; + break; + case ProtocolType.HTTPS: + if (host.HTTPS) + finalProtocol = ProtocolType.HTTPS; + break; + case ProtocolType.Rlogin: + if (host.Rlogin) + finalProtocol = ProtocolType.Rlogin; + break; + case ProtocolType.RDP: + if (host.RDP) + finalProtocol = ProtocolType.RDP; + break; + case ProtocolType.VNC: + if (host.VNC) + finalProtocol = ProtocolType.VNC; + break; + default: + protocolValid = false; + break; + } + + if (!protocolValid) return; + var newConnectionInfo = new ConnectionInfo + { + Name = host.HostNameWithoutDomain, + Hostname = host.HostName, + Protocol = finalProtocol + }; + newConnectionInfo.SetDefaultPort(); + + parentContainer.AddChild(newConnectionInfo); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/PuttyConnectionManagerDeserializer.cs b/mRemoteV1/Config/Serializers/PuttyConnectionManagerDeserializer.cs new file mode 100644 index 000000000..8574ce317 --- /dev/null +++ b/mRemoteV1/Config/Serializers/PuttyConnectionManagerDeserializer.cs @@ -0,0 +1,159 @@ +using System; +using System.IO; +using System.Xml; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class PuttyConnectionManagerDeserializer : IDeserializer + { + private readonly string _puttycmConnectionsXml; + + public PuttyConnectionManagerDeserializer(string xml) + { + _puttycmConnectionsXml = xml; + } + + public ConnectionTreeModel Deserialize() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + connectionTreeModel.AddRootNode(root); + + var xmlDocument = new XmlDocument(); + xmlDocument.LoadXml(_puttycmConnectionsXml); + + var configurationNode = xmlDocument.SelectSingleNode("/configuration"); + + var rootNodes = configurationNode?.SelectNodes("./root"); + if (rootNodes == null) return connectionTreeModel; + foreach (XmlNode rootNode in rootNodes) + { + ImportRootOrContainer(rootNode, root); + } + + return connectionTreeModel; + } + + private void ImportRootOrContainer(XmlNode xmlNode, ContainerInfo parentContainer) + { + VerifyNodeType(xmlNode); + + var newContainer = ImportContainer(xmlNode, parentContainer); + + var childNodes = xmlNode.SelectNodes("./*"); + if (childNodes == null) return; + foreach (XmlNode childNode in childNodes) + { + switch (childNode.Name) + { + case "container": + ImportRootOrContainer(childNode, newContainer); + break; + case "connection": + ImportConnection(childNode, newContainer); + break; + default: + throw (new FileFormatException($"Unrecognized child node ({childNode.Name}).")); + } + } + } + + private void VerifyNodeType(XmlNode xmlNode) + { + var xmlNodeType = xmlNode?.Attributes?["type"].Value; + switch (xmlNode?.Name) + { + case "root": + if (string.Compare(xmlNodeType, "database", StringComparison.OrdinalIgnoreCase) != 0) + { + throw (new FileFormatException($"Unrecognized root node type ({xmlNodeType}).")); + } + break; + case "container": + if (string.Compare(xmlNodeType, "folder", StringComparison.OrdinalIgnoreCase) != 0) + { + throw (new FileFormatException($"Unrecognized root node type ({xmlNodeType}).")); + } + break; + default: + // ReSharper disable once LocalizableElement + throw (new ArgumentException("Argument must be either a root or a container node.", nameof(xmlNode))); + } + } + + private ContainerInfo ImportContainer(XmlNode containerNode, ContainerInfo parentContainer) + { + var containerInfo = new ContainerInfo + { + Name = containerNode.Attributes?["name"].Value, + IsExpanded = bool.Parse(containerNode.Attributes?["expanded"].InnerText ?? "false") + }; + parentContainer.AddChild(containerInfo); + return containerInfo; + } + + private void ImportConnection(XmlNode connectionNode, ContainerInfo parentContainer) + { + var connectionNodeType = connectionNode.Attributes?["type"].Value; + if (string.Compare(connectionNodeType, "PuTTY", StringComparison.OrdinalIgnoreCase) != 0) + throw (new FileFormatException($"Unrecognized connection node type ({connectionNodeType}).")); + + var connectionInfo = ConnectionInfoFromXml(connectionNode); + parentContainer.AddChild(connectionInfo); + } + + private ConnectionInfo ConnectionInfoFromXml(XmlNode xmlNode) + { + var connectionInfoNode = xmlNode.SelectSingleNode("./connection_info"); + + var name = connectionInfoNode?.SelectSingleNode("./name")?.InnerText; + var connectionInfo = new ConnectionInfo {Name = name}; + + var protocol = connectionInfoNode?.SelectSingleNode("./protocol")?.InnerText; + switch (protocol?.ToLowerInvariant()) + { + case "telnet": + connectionInfo.Protocol = ProtocolType.Telnet; + break; + case "ssh": + connectionInfo.Protocol = ProtocolType.SSH2; + break; + default: + throw new FileFormatException($"Unrecognized protocol ({protocol})."); + } + + connectionInfo.Hostname = connectionInfoNode.SelectSingleNode("./host")?.InnerText; + connectionInfo.Port = Convert.ToInt32(connectionInfoNode.SelectSingleNode("./port")?.InnerText); + connectionInfo.PuttySession = connectionInfoNode.SelectSingleNode("./session")?.InnerText; + // ./commandline + connectionInfo.Description = connectionInfoNode.SelectSingleNode("./description")?.InnerText; + + var loginNode = xmlNode.SelectSingleNode("./login"); + connectionInfo.Username = loginNode?.SelectSingleNode("login")?.InnerText; + connectionInfo.Password = loginNode?.SelectSingleNode("password")?.InnerText; + // ./prompt + + // ./timeout/connectiontimeout + // ./timeout/logintimeout + // ./timeout/passwordtimeout + // ./timeout/commandtimeout + + // ./command/command1 + // ./command/command2 + // ./command/command3 + // ./command/command4 + // ./command/command5 + + // ./options/loginmacro + // ./options/postcommands + // ./options/endlinechar + + return connectionInfo; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/RemoteDesktopConnectionDeserializer.cs b/mRemoteV1/Config/Serializers/RemoteDesktopConnectionDeserializer.cs new file mode 100644 index 000000000..8000d8682 --- /dev/null +++ b/mRemoteV1/Config/Serializers/RemoteDesktopConnectionDeserializer.cs @@ -0,0 +1,134 @@ +using System; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class RemoteDesktopConnectionDeserializer : IDeserializer + { + // .rdp file schema: https://technet.microsoft.com/en-us/library/ff393699(v=ws.10).aspx + private readonly string[] _fileContent; + + public RemoteDesktopConnectionDeserializer(string[] fileContent) + { + _fileContent = fileContent; + } + + public ConnectionTreeModel Deserialize() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + connectionTreeModel.AddRootNode(root); + var connectionInfo = new ConnectionInfo(); + foreach (var line in _fileContent) + { + var parts = line.Split(new[] { ':' }, 3); + if (parts.Length < 3) + { + continue; + } + + var key = parts[0]; + var value = parts[2]; + + SetConnectionInfoParameter(connectionInfo, key, value); + } + root.AddChild(connectionInfo); + + return connectionTreeModel; + } + + + private void SetConnectionInfoParameter(ConnectionInfo connectionInfo, string key, string value) + { + switch (key.ToLower()) + { + case "full address": + var uri = new Uri("dummyscheme" + Uri.SchemeDelimiter + value); + if (!string.IsNullOrEmpty(uri.Host)) + connectionInfo.Hostname = uri.Host; + if (uri.Port != -1) + connectionInfo.Port = uri.Port; + break; + case "server port": + connectionInfo.Port = Convert.ToInt32(value); + break; + case "username": + connectionInfo.Username = value; + break; + case "domain": + connectionInfo.Domain = value; + break; + case "session bpp": + switch (value) + { + case "8": + connectionInfo.Colors = ProtocolRDP.RDPColors.Colors256; + break; + case "15": + connectionInfo.Colors = ProtocolRDP.RDPColors.Colors15Bit; + break; + case "16": + connectionInfo.Colors = ProtocolRDP.RDPColors.Colors16Bit; + break; + case "24": + connectionInfo.Colors = ProtocolRDP.RDPColors.Colors24Bit; + break; + case "32": + connectionInfo.Colors = ProtocolRDP.RDPColors.Colors32Bit; + break; + } + break; + case "bitmapcachepersistenable": + connectionInfo.CacheBitmaps = value == "1"; + break; + case "screen mode id": + connectionInfo.Resolution = value == "2" ? ProtocolRDP.RDPResolutions.Fullscreen : ProtocolRDP.RDPResolutions.FitToWindow; + break; + case "connect to console": + connectionInfo.UseConsoleSession = value == "1"; + break; + case "disable wallpaper": + connectionInfo.DisplayWallpaper = value == "1"; + break; + case "disable themes": + connectionInfo.DisplayThemes = value == "1"; + break; + case "allow font smoothing": + connectionInfo.EnableFontSmoothing = value == "1"; + break; + case "allow desktop composition": + connectionInfo.EnableDesktopComposition = value == "1"; + break; + case "redirectsmartcards": + connectionInfo.RedirectSmartCards = value == "1"; + break; + case "redirectdrives": + connectionInfo.RedirectDiskDrives = value == "1"; + break; + case "redirectcomports": + connectionInfo.RedirectPorts = value == "1"; + break; + case "redirectprinters": + connectionInfo.RedirectPrinters = value == "1"; + break; + case "audiomode": + switch (value) + { + case "0": + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.BringToThisComputer; + break; + case "1": + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.LeaveAtRemoteComputer; + break; + case "2": + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.DoNotPlay; + break; + } + break; + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/RemoteDesktopConnectionManagerDeserializer.cs b/mRemoteV1/Config/Serializers/RemoteDesktopConnectionManagerDeserializer.cs new file mode 100644 index 000000000..242ab3a2b --- /dev/null +++ b/mRemoteV1/Config/Serializers/RemoteDesktopConnectionManagerDeserializer.cs @@ -0,0 +1,303 @@ +using System; +using System.IO; +using System.Xml; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Container; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; +using System.Security.Cryptography; +using System.Text; + + +namespace mRemoteNG.Config.Serializers +{ + public class RemoteDesktopConnectionManagerDeserializer : IDeserializer + { + private readonly string _rdcmConnectionsXml; + + public RemoteDesktopConnectionManagerDeserializer(string xml) + { + _rdcmConnectionsXml = xml; + } + + public ConnectionTreeModel Deserialize() + { + var connectionTreeModel = new ConnectionTreeModel(); + var root = new RootNodeInfo(RootNodeType.Connection); + + var xmlDocument = new XmlDocument(); + xmlDocument.LoadXml(_rdcmConnectionsXml); + + + var rdcManNode = xmlDocument.SelectSingleNode("/RDCMan"); + VerifySchemaVersion(rdcManNode); + VerifyFileVersion(rdcManNode); + + var fileNode = rdcManNode?.SelectSingleNode("./file"); + ImportFileOrGroup(fileNode, root); + + connectionTreeModel.AddRootNode(root); + return connectionTreeModel; + } + + private void VerifySchemaVersion(XmlNode rdcManNode) + { + var schemaVersion = Convert.ToInt32(rdcManNode?.Attributes?["schemaVersion"].Value); + if (schemaVersion != 1) + { + throw (new FileFormatException($"Unsupported schema version ({schemaVersion}).")); + } + } + + private void VerifyFileVersion(XmlNode rdcManNode) + { + var versionNode = rdcManNode.SelectSingleNode("./version")?.InnerText; + if (versionNode != null) + { + var version = new Version(versionNode); + if (!(version == new Version(2, 2))) + { + throw new FileFormatException($"Unsupported file version ({version})."); + } + } + else + { + throw new FileFormatException("Unknown file version"); + } + } + + private void ImportFileOrGroup(XmlNode xmlNode, ContainerInfo parentContainer) + { + var propertiesNode = xmlNode.SelectSingleNode("./properties"); + var newContainer = ImportContainer(propertiesNode, parentContainer); + + var childNodes = xmlNode.SelectNodes("./group|./server"); + if (childNodes == null) return; + foreach (XmlNode childNode in childNodes) + { + switch (childNode.Name) + { + case "group": + ImportFileOrGroup(childNode, newContainer); + break; + case "server": + ImportServer(childNode, newContainer); + break; + } + } + } + + private ContainerInfo ImportContainer(XmlNode containerPropertiesNode, ContainerInfo parentContainer) + { + var newContainer = new ContainerInfo(); + var connectionInfo = ConnectionInfoFromXml(containerPropertiesNode); + newContainer.CopyFrom(connectionInfo); + newContainer.Name = containerPropertiesNode?.SelectSingleNode("./name")?.InnerText ?? Language.strNewFolder; + newContainer.IsExpanded = bool.Parse(containerPropertiesNode?.SelectSingleNode("./expanded")?.InnerText ?? "false"); + parentContainer.AddChild(newContainer); + return newContainer; + } + + private void ImportServer(XmlNode serverNode, ContainerInfo parentContainer) + { + var newConnectionInfo = ConnectionInfoFromXml(serverNode); + parentContainer.AddChild(newConnectionInfo); + } + + private ConnectionInfo ConnectionInfoFromXml(XmlNode xmlNode) + { + var connectionInfo = new ConnectionInfo {Protocol = ProtocolType.RDP}; + + var hostname = xmlNode.SelectSingleNode("./name")?.InnerText; + + var displayName = xmlNode.SelectSingleNode("./displayName")?.InnerText ?? Language.strNewConnection; + + connectionInfo.Name = displayName; + connectionInfo.Description = xmlNode.SelectSingleNode("./comment")?.InnerText; + connectionInfo.Hostname = hostname; + + var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials"); + if (logonCredentialsNode?.Attributes?["inherit"].Value == "None") + { + connectionInfo.Username = logonCredentialsNode.SelectSingleNode("userName")?.InnerText; + + var passwordNode = logonCredentialsNode.SelectSingleNode("./password"); + connectionInfo.Password = passwordNode?.Attributes?["storeAsClearText"].Value == "True" ? passwordNode.InnerText : DecryptRdcManPassword(passwordNode?.InnerText); + + connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText; + } + else + { + connectionInfo.Inheritance.Username = true; + connectionInfo.Inheritance.Password = true; + connectionInfo.Inheritance.Domain = true; + } + + var connectionSettingsNode = xmlNode.SelectSingleNode("./connectionSettings"); + if (connectionSettingsNode?.Attributes?["inherit"].Value == "None") + { + connectionInfo.UseConsoleSession = bool.Parse(connectionSettingsNode.SelectSingleNode("./connectToConsole")?.InnerText ?? "false"); + // ./startProgram + // ./workingDir + connectionInfo.Port = Convert.ToInt32(connectionSettingsNode.SelectSingleNode("./port")?.InnerText); + } + else + { + connectionInfo.Inheritance.UseConsoleSession = true; + connectionInfo.Inheritance.Port = true; + } + + var gatewaySettingsNode = xmlNode.SelectSingleNode("./gatewaySettings"); + if (gatewaySettingsNode?.Attributes?["inherit"].Value == "None") + { + connectionInfo.RDGatewayUsageMethod = gatewaySettingsNode.SelectSingleNode("./enabled")?.InnerText == "True" ? ProtocolRDP.RDGatewayUsageMethod.Always : ProtocolRDP.RDGatewayUsageMethod.Never; + connectionInfo.RDGatewayHostname = gatewaySettingsNode.SelectSingleNode("./hostName")?.InnerText; + connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName")?.InnerText; + + var passwordNode = gatewaySettingsNode.SelectSingleNode("./password"); + connectionInfo.RDGatewayPassword = passwordNode?.Attributes?["storeAsClearText"].Value == "True" ? passwordNode.InnerText : DecryptRdcManPassword(passwordNode?.InnerText); + + connectionInfo.RDGatewayDomain = gatewaySettingsNode.SelectSingleNode("./domain")?.InnerText; + // ./logonMethod + // ./localBypass + // ./credSharing + } + else + { + connectionInfo.Inheritance.RDGatewayUsageMethod = true; + connectionInfo.Inheritance.RDGatewayHostname = true; + connectionInfo.Inheritance.RDGatewayUsername = true; + connectionInfo.Inheritance.RDGatewayPassword = true; + connectionInfo.Inheritance.RDGatewayDomain = true; + } + + var remoteDesktopNode = xmlNode.SelectSingleNode("./remoteDesktop"); + if (remoteDesktopNode?.Attributes?["inherit"].Value == "None") + { + var resolutionString = Convert.ToString(remoteDesktopNode.SelectSingleNode("./size")?.InnerText.Replace(" ", "")); + try + { + connectionInfo.Resolution = (ProtocolRDP.RDPResolutions)Enum.Parse(typeof(ProtocolRDP.RDPResolutions), "Res" + resolutionString); + } + catch (ArgumentException) + { + connectionInfo.Resolution = ProtocolRDP.RDPResolutions.FitToWindow; + } + + if (remoteDesktopNode.SelectSingleNode("./sameSizeAsClientArea")?.InnerText == "True") + { + connectionInfo.Resolution = ProtocolRDP.RDPResolutions.FitToWindow; + } + + if (remoteDesktopNode.SelectSingleNode("./fullScreen")?.InnerText == "True") + { + connectionInfo.Resolution = ProtocolRDP.RDPResolutions.Fullscreen; + } + + var colorDepth = remoteDesktopNode.SelectSingleNode("./colorDepth")?.InnerText; + if (colorDepth != null) + connectionInfo.Colors = (ProtocolRDP.RDPColors)Enum.Parse(typeof(ProtocolRDP.RDPColors), colorDepth); + } + else + { + connectionInfo.Inheritance.Resolution = true; + connectionInfo.Inheritance.Colors = true; + } + + var localResourcesNode = xmlNode.SelectSingleNode("./localResources"); + if (localResourcesNode?.Attributes?["inherit"].Value == "None") + { + switch (localResourcesNode.SelectSingleNode("./audioRedirection")?.InnerText) + { + case "0": // Bring to this computer + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.BringToThisComputer; + break; + case "1": // Leave at remote computer + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.LeaveAtRemoteComputer; + break; + case "2": // Do not play + connectionInfo.RedirectSound = ProtocolRDP.RDPSounds.DoNotPlay; + break; + } + + // ./audioRedirectionQuality + // ./audioCaptureRedirection + + switch (localResourcesNode.SelectSingleNode("./keyboardHook")?.InnerText) + { + case "0": // On the local computer + connectionInfo.RedirectKeys = false; + break; + case "1": // On the remote computer + connectionInfo.RedirectKeys = true; + break; + case "2": // In full screen mode only + connectionInfo.RedirectKeys = false; + break; + } + + // ./redirectClipboard + connectionInfo.RedirectDiskDrives = bool.Parse(localResourcesNode.SelectSingleNode("./redirectDrives")?.InnerText ?? "false"); + connectionInfo.RedirectPorts = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPorts")?.InnerText ?? "false"); + connectionInfo.RedirectPrinters = bool.Parse(localResourcesNode.SelectSingleNode("./redirectPrinters")?.InnerText ?? "false"); + connectionInfo.RedirectSmartCards = bool.Parse(localResourcesNode.SelectSingleNode("./redirectSmartCards")?.InnerText ?? "false"); + } + else + { + connectionInfo.Inheritance.RedirectSound = true; + connectionInfo.Inheritance.RedirectKeys = true; + connectionInfo.Inheritance.RedirectDiskDrives = true; + connectionInfo.Inheritance.RedirectPorts = true; + connectionInfo.Inheritance.RedirectPrinters = true; + connectionInfo.Inheritance.RedirectSmartCards = true; + } + + var securitySettingsNode = xmlNode.SelectSingleNode("./securitySettings"); + if (securitySettingsNode?.Attributes?["inherit"].Value == "None") + { + switch (securitySettingsNode.SelectSingleNode("./authentication")?.InnerText) + { + case "0": // No authentication + connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.NoAuth; + break; + case "1": // Do not connect if authentication fails + connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.AuthRequired; + break; + case "2": // Warn if authentication fails + connectionInfo.RDPAuthenticationLevel = ProtocolRDP.AuthenticationLevel.WarnOnFailedAuth; + break; + } + } + else + { + connectionInfo.Inheritance.RDPAuthenticationLevel = true; + } + + // ./displaySettings/thumbnailScale + // ./displaySettings/liveThumbnailUpdates + // ./displaySettings/showDisconnectedThumbnails + + return connectionInfo; + } + + private string DecryptRdcManPassword(string ciphertext) + { + if (string.IsNullOrEmpty(ciphertext)) + return null; + + try + { + var plaintextData = ProtectedData.Unprotect(Convert.FromBase64String(ciphertext), new byte[] { }, DataProtectionScope.LocalMachine); + var charArray = Encoding.Unicode.GetChars(plaintextData); + return new string(charArray); + } + catch (Exception ex) + { + //Runtime.MessageCollector.AddExceptionMessage("RemoteDesktopConnectionManager.DecryptPassword() failed.", ex, logOnly: true); + return null; + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs similarity index 70% rename from mRemoteV1/Config/Connections/XmlConnectionsLoader.cs rename to mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs index bf46603c8..1e386bbde 100644 --- a/mRemoteV1/Config/Connections/XmlConnectionsLoader.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsDeserializer.cs @@ -1,11 +1,9 @@ using System; using System.Globalization; -using System.IO; -using System.Security; using System.Windows.Forms; using System.Xml; using mRemoteNG.App; -using mRemoteNG.App.Info; +using mRemoteNG.Config.Connections; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; using mRemoteNG.Connection.Protocol.Http; @@ -14,7 +12,6 @@ using mRemoteNG.Connection.Protocol.RDP; using mRemoteNG.Connection.Protocol.VNC; using mRemoteNG.Container; using mRemoteNG.Messages; -using mRemoteNG.Security; using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; @@ -22,64 +19,100 @@ using mRemoteNG.UI.Forms; using mRemoteNG.UI.TaskDialog; -namespace mRemoteNG.Config.Connections +namespace mRemoteNG.Config.Serializers { - public class XmlConnectionsLoader + public class XmlConnectionsDeserializer : IDeserializer { private XmlDocument _xmlDocument; private double _confVersion; - private SecureString _pW = GeneralAppInfo.EncryptionKey; - private ContainerInfo _previousContainer; + private readonly ConnectionsDecryptor _decryptor = new ConnectionsDecryptor(); + //TODO find way to inject data source info + private string ConnectionFileName = ""; + public XmlConnectionsDeserializer(string xml) + { + LoadXmlConnectionData(xml); + ValidateConnectionFileVersion(); + } - public string ConnectionFileName { get; set; } - public TreeNode RootTreeNode { get; set; } - public ConnectionList ConnectionList { get; set; } - public ContainerList ContainerList { get; set; } + private void LoadXmlConnectionData(string connections) + { + connections = _decryptor.DecryptConnections(connections); + _xmlDocument = new XmlDocument(); + if (connections != "") + _xmlDocument.LoadXml(connections); + } + private void ValidateConnectionFileVersion() + { + if (_xmlDocument.DocumentElement != null && _xmlDocument.DocumentElement.HasAttribute("ConfVersion")) + _confVersion = Convert.ToDouble(_xmlDocument.DocumentElement.Attributes["ConfVersion"].Value.Replace(",", "."), + CultureInfo.InvariantCulture); + else + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strOldConffile); - public void LoadFromXml(bool import) + const double maxSupportedConfVersion = 2.5; + if (!(_confVersion > maxSupportedConfVersion)) return; + CTaskDialog.ShowTaskDialogBox( + frmMain.Default, + Application.ProductName, + "Incompatible connection file format", + $"The format of this connection file is not supported. Please upgrade to a newer version of {Application.ProductName}.", + string.Format("{1}{0}File Format Version: {2}{0}Highest Supported Version: {3}", Environment.NewLine, + ConnectionFileName, _confVersion, maxSupportedConfVersion), + "", + "", + "", + "", + ETaskDialogButtons.Ok, + ESysIcons.Error, + ESysIcons.Error + ); + throw (new Exception($"Incompatible connection file format (file format version {_confVersion}).")); + } + + public ConnectionTreeModel Deserialize() + { + return Deserialize(false); + } + + public ConnectionTreeModel Deserialize(bool import) { try { if (!import) Runtime.IsConnectionsFileLoaded = false; - - // SECTION 1. Create a DOM Document and load the XML data into it. - LoadXmlConnectionData(); - ValidateConnectionFileVersion(); - - // SECTION 2. Initialize the treeview control. var rootInfo = InitializeRootNode(); + var connectionTreeModel = new ConnectionTreeModel(); + connectionTreeModel.AddRootNode(rootInfo); - if (!ConnectionsFileIsAuthentic(rootInfo)) return; + if (_confVersion > 1.3) + { + var protectedString = _xmlDocument.DocumentElement?.Attributes["Protected"].Value; + if (!_decryptor.ConnectionsFileIsAuthentic(protectedString, rootInfo)) + { + mRemoteNG.Settings.Default.LoadConsFromCustomLocation = false; + mRemoteNG.Settings.Default.CustomConsPath = ""; + return null; + } + } if (import && !IsExportFile()) { Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strCannotImportNormalSessionFile); - return; + return null; } - if (!IsExportFile()) - { - RootTreeNode.ImageIndex = (int)TreeImageType.Root; - RootTreeNode.SelectedImageIndex = (int)TreeImageType.Root; - } + AddNodesFromXmlRecursive(_xmlDocument.DocumentElement, rootInfo); + //Windows.treeForm.InitialRefresh(); + //SetSelectedNode(RootTreeNode); - // SECTION 3. Populate the TreeView with the DOM nodes. - PopulateTreeview(); - RootTreeNode.EnsureVisible(); - Windows.treeForm.InitialRefresh(); - SetSelectedNode(RootTreeNode); - - //open connections from last mremote session - OpenConnectionsFromLastSession(); - - if (!import) Runtime.IsConnectionsFileLoaded = true; + + return connectionTreeModel; } catch (Exception ex) { @@ -89,66 +122,33 @@ namespace mRemoteNG.Config.Connections } } - private bool ConnectionsFileIsAuthentic(RootNodeInfo rootInfo) - { - if (!(_confVersion > 1.3)) return true; - var protectedString = _xmlDocument.DocumentElement.Attributes["Protected"].Value; - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - var connectionsFileIsNotEncrypted = cryptographyProvider.Decrypt(protectedString, _pW) == "ThisIsNotProtected"; - if (connectionsFileIsNotEncrypted) return true; - if (Authenticate(protectedString, false, rootInfo)) return true; - mRemoteNG.Settings.Default.LoadConsFromCustomLocation = false; - mRemoteNG.Settings.Default.CustomConsPath = ""; - RootTreeNode.Remove(); - return false; - } - - private void OpenConnectionsFromLastSession() - { - if (!mRemoteNG.Settings.Default.OpenConsFromLastSession || mRemoteNG.Settings.Default.NoReconnect) return; - foreach (ConnectionInfo conI in ConnectionList) - { - if (conI.PleaseConnect) - Runtime.OpenConnection(conI); - } - } - - private void PopulateTreeview() - { - Windows.treeForm.tvConnections.BeginUpdate(); - AddNodeFromXml(_xmlDocument.DocumentElement, RootTreeNode); - RootTreeNode.Expand(); - ExpandPreviouslyOpenedFolders(); - Windows.treeForm.tvConnections.EndUpdate(); - } - - private void AddNodeFromXml(XmlNode parentXmlNode, TreeNode parentTreeNode) + private void AddNodesFromXmlRecursive(XmlNode parentXmlNode, ContainerInfo parentContainer) { try { - // Loop through the XML nodes until the leaf is reached. - // Add the nodes to the TreeView during the looping process. - if (parentXmlNode.HasChildNodes) + if (!parentXmlNode.HasChildNodes) return; + foreach (XmlNode xmlNode in parentXmlNode.ChildNodes) { - foreach (XmlNode xmlNode in parentXmlNode.ChildNodes) + var treeNodeTypeString = xmlNode.Attributes?["Type"].Value ?? "connection"; + var nodeType = (TreeNodeType)Enum.Parse(typeof(TreeNodeType), treeNodeTypeString, true); + + if (nodeType == TreeNodeType.Connection) { - var treeNode = new TreeNode(xmlNode.Attributes?["Name"].Value); - parentTreeNode.Nodes.Add(treeNode); - var nodeType = ConnectionTreeNode.GetNodeTypeFromString(xmlNode.Attributes?["Type"].Value); - - if (nodeType == TreeNodeType.Connection) - AddConnectionToList(xmlNode, treeNode); - else if (nodeType == TreeNodeType.Container) - AddContainerToList(xmlNode, treeNode); - - AddNodeFromXml(xmlNode, treeNode); + var connectionInfo = GetConnectionInfoFromXml(xmlNode); + parentContainer.AddChild(connectionInfo); + } + else if (nodeType == TreeNodeType.Container) + { + var containerInfo = new ContainerInfo(); + + if (_confVersion >= 0.9) + containerInfo.CopyFrom(GetConnectionInfoFromXml(xmlNode)); + if (_confVersion >= 0.8) + containerInfo.IsExpanded = xmlNode.Attributes?["Expanded"].Value == "True"; + + parentContainer.AddChild(containerInfo); + AddNodesFromXmlRecursive(xmlNode, containerInfo); } - } - else - { - var nameAttribute = parentXmlNode.Attributes?["Name"]; - var nodeName = nameAttribute?.Value.Trim(); - parentTreeNode.Text = !string.IsNullOrEmpty(nodeName) ? nodeName : parentXmlNode.Name; } } catch (Exception ex) @@ -158,39 +158,6 @@ namespace mRemoteNG.Config.Connections } } - private void AddConnectionToList(XmlNode xmlNode, TreeNode treeNode) - { - var connectionInfo = GetConnectionInfoFromXml(xmlNode); - connectionInfo.TreeNode = treeNode; - connectionInfo.Parent = _previousContainer; - ConnectionList.Add(connectionInfo); - treeNode.Tag = connectionInfo; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - } - - private void AddContainerToList(XmlNode xmlNode, TreeNode treeNode) - { - var containerInfo = new ContainerInfo(); - - if (_confVersion >= 0.8) - containerInfo.IsExpanded = xmlNode.Attributes?["Expanded"].Value == "True"; - if (_confVersion >= 0.9) - containerInfo.CopyFrom(GetConnectionInfoFromXml(xmlNode)); - - if (treeNode.Parent?.Tag is ContainerInfo) - containerInfo.Parent = (ContainerInfo) treeNode.Parent.Tag; - - containerInfo.TreeNode = treeNode; - containerInfo.Name = xmlNode.Attributes?["Name"].Value; - - _previousContainer = containerInfo; - ContainerList.Add(containerInfo); - treeNode.Tag = containerInfo; - treeNode.ImageIndex = (int) TreeImageType.Container; - treeNode.SelectedImageIndex = (int) TreeImageType.Container; - } - private ConnectionInfo GetConnectionInfoFromXml(XmlNode xxNode) { var connectionInfo = new ConnectionInfo(); @@ -204,7 +171,7 @@ namespace mRemoteNG.Config.Connections connectionInfo.Description = xmlnode.Attributes["Descr"].Value; connectionInfo.Hostname = xmlnode.Attributes["Hostname"].Value; connectionInfo.Username = xmlnode.Attributes["Username"].Value; - connectionInfo.Password = cryptographyProvider.Decrypt(xmlnode.Attributes["Password"].Value, _pW); + connectionInfo.Password = cryptographyProvider.Decrypt(xmlnode.Attributes["Password"].Value, Runtime.EncryptionKey); connectionInfo.Domain = xmlnode.Attributes["Domain"].Value; connectionInfo.DisplayWallpaper = bool.Parse(xmlnode.Attributes["DisplayWallpaper"].Value); connectionInfo.DisplayThemes = bool.Parse(xmlnode.Attributes["DisplayThemes"].Value); @@ -384,7 +351,7 @@ namespace mRemoteNG.Config.Connections connectionInfo.VNCProxyIP = xmlnode.Attributes["VNCProxyIP"].Value; connectionInfo.VNCProxyPort = Convert.ToInt32(xmlnode.Attributes["VNCProxyPort"].Value); connectionInfo.VNCProxyUsername = xmlnode.Attributes["VNCProxyUsername"].Value; - connectionInfo.VNCProxyPassword = cryptographyProvider.Decrypt(xmlnode.Attributes["VNCProxyPassword"].Value, _pW); + connectionInfo.VNCProxyPassword = cryptographyProvider.Decrypt(xmlnode.Attributes["VNCProxyPassword"].Value, Runtime.EncryptionKey); connectionInfo.VNCColors = (ProtocolVNC.Colors)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.Colors), xmlnode.Attributes["VNCColors"].Value); connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Tools.MiscTools.StringToEnum(typeof(ProtocolVNC.SmartSizeMode), xmlnode.Attributes["VNCSmartSizeMode"].Value); connectionInfo.VNCViewOnly = bool.Parse(xmlnode.Attributes["VNCViewOnly"].Value); @@ -434,7 +401,7 @@ namespace mRemoteNG.Config.Connections connectionInfo.RDGatewayHostname = xmlnode.Attributes["RDGatewayHostname"].Value; connectionInfo.RDGatewayUseConnectionCredentials = (ProtocolRDP.RDGatewayUseConnectionCredentials)Tools.MiscTools.StringToEnum(typeof(ProtocolRDP.RDGatewayUseConnectionCredentials), Convert.ToString(xmlnode.Attributes["RDGatewayUseConnectionCredentials"].Value)); connectionInfo.RDGatewayUsername = xmlnode.Attributes["RDGatewayUsername"].Value; - connectionInfo.RDGatewayPassword = cryptographyProvider.Decrypt(Convert.ToString(xmlnode.Attributes["RDGatewayPassword"].Value), _pW); + connectionInfo.RDGatewayPassword = cryptographyProvider.Decrypt(Convert.ToString(xmlnode.Attributes["RDGatewayPassword"].Value), Runtime.EncryptionKey); connectionInfo.RDGatewayDomain = xmlnode.Attributes["RDGatewayDomain"].Value; // Get inheritance settings @@ -478,16 +445,6 @@ namespace mRemoteNG.Config.Connections return connectionInfo; } - - private void ExpandPreviouslyOpenedFolders() - { - foreach (ContainerInfo contI in ContainerList) - { - if (contI.IsExpanded) - contI.TreeNode.Expand(); - } - } - private bool IsExportFile() { var isExportFile = false; @@ -499,147 +456,13 @@ namespace mRemoteNG.Config.Connections private RootNodeInfo InitializeRootNode() { - var rootNodeName = ""; - if (_xmlDocument.DocumentElement.HasAttribute("Name")) - rootNodeName = Convert.ToString(_xmlDocument.DocumentElement.Attributes["Name"].Value.Trim()); - RootTreeNode.Name = !string.IsNullOrEmpty(rootNodeName) ? rootNodeName : _xmlDocument.DocumentElement.Name; - RootTreeNode.Text = RootTreeNode.Name; + var rootNodeName = _xmlDocument.DocumentElement?.Attributes["Name"].Value.Trim(); var rootInfo = new RootNodeInfo(RootNodeType.Connection) { - Name = RootTreeNode.Name, - TreeNode = RootTreeNode + Name = rootNodeName }; - RootTreeNode.Tag = rootInfo; return rootInfo; } - - private void LoadXmlConnectionData() - { - var connections = DecryptCompleteFile(); - _xmlDocument = new XmlDocument(); - if (connections != "") - _xmlDocument.LoadXml(connections); - else - _xmlDocument.Load(ConnectionFileName); - } - - private void ValidateConnectionFileVersion() - { - if (_xmlDocument.DocumentElement.HasAttribute("ConfVersion")) - _confVersion = Convert.ToDouble(_xmlDocument.DocumentElement.Attributes["ConfVersion"].Value.Replace(",", "."), - CultureInfo.InvariantCulture); - else - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strOldConffile); - - const double maxSupportedConfVersion = 2.5; - if (!(_confVersion > maxSupportedConfVersion)) return; - CTaskDialog.ShowTaskDialogBox( - frmMain.Default, - Application.ProductName, - "Incompatible connection file format", - $"The format of this connection file is not supported. Please upgrade to a newer version of {Application.ProductName}.", - string.Format("{1}{0}File Format Version: {2}{0}Highest Supported Version: {3}", Environment.NewLine, - ConnectionFileName, _confVersion, maxSupportedConfVersion), - "", - "", - "", - "", - ETaskDialogButtons.Ok, - ESysIcons.Error, - ESysIcons.Error - ); - throw (new Exception($"Incompatible connection file format (file format version {_confVersion}).")); - } - - private delegate void SetSelectedNodeDelegate(TreeNode treeNode); - private static void SetSelectedNode(TreeNode treeNode) - { - if (ConnectionTree.TreeView != null && ConnectionTree.TreeView.InvokeRequired) - { - Windows.treeForm.Invoke(new SetSelectedNodeDelegate(SetSelectedNode), treeNode); - return; - } - Windows.treeForm.tvConnections.SelectedNode = treeNode; - } - - private string DecryptCompleteFile() - { - var sRd = new StreamReader(ConnectionFileName); - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - var strCons = ""; - strCons = sRd.ReadToEnd(); - sRd.Close(); - - if (string.IsNullOrEmpty(strCons)) return ""; - var strDecr = ""; - bool notDecr; - - if (strCons.Contains("")) - { - strDecr = strCons; - return strDecr; - } - - try - { - strDecr = cryptographyProvider.Decrypt(strCons, _pW); - notDecr = strDecr == strCons; - } - catch (Exception) - { - notDecr = true; - } - - if (notDecr) - { - if (Authenticate(strCons, true)) - { - strDecr = cryptographyProvider.Decrypt(strCons, _pW); - notDecr = false; - } - - if (notDecr == false) - return strDecr; - } - else - { - return strDecr; - } - - return ""; - } - - private bool Authenticate(string value, bool compareToOriginalValue, RootNodeInfo rootInfo = null) - { - var passwordName = ""; - var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); - passwordName = Path.GetFileName(ConnectionFileName); - - if (compareToOriginalValue) - { - while (cryptographyProvider.Decrypt(value, _pW) == value) - { - _pW = Tools.MiscTools.PasswordDialog(passwordName, false); - if (_pW.Length == 0) - return false; - } - } - else - { - while (cryptographyProvider.Decrypt(value, _pW) != "ThisIsProtected") - { - _pW = Tools.MiscTools.PasswordDialog(passwordName, false); - if (_pW.Length == 0) - return false; - } - - if (rootInfo == null) return true; - rootInfo.Password = true; - rootInfo.PasswordString = _pW.ConvertToUnsecureString(); - } - - return true; - } } } \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs new file mode 100644 index 000000000..e4483bd11 --- /dev/null +++ b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs @@ -0,0 +1,345 @@ +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security; +using System.Text; +using System.Xml; +using mRemoteNG.App; +using mRemoteNG.App.Info; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Messages; +using mRemoteNG.Security; +using mRemoteNG.Security.SymmetricEncryption; +using mRemoteNG.Tree; +using mRemoteNG.Tree.Root; + +namespace mRemoteNG.Config.Serializers +{ + public class XmlConnectionsSerializer : ISerializer + { + private SecureString _password = GeneralAppInfo.EncryptionKey; + private XmlTextWriter _xmlTextWriter; + + public bool Export { get; set; } + public Save SaveSecurity { get; set; } + + + public string Serialize(ConnectionTreeModel connectionTreeModel) + { + var rootNode = (RootNodeInfo)connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); + return Serialize(rootNode); + } + + public string Serialize(ConnectionInfo serializationTarget) + { + var xml = ""; + try + { + var memoryStream = new MemoryStream(); + using (_xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8)) + { + SetXmlTextWriterSettings(); + _xmlTextWriter.WriteStartDocument(); + SaveNodesRecursive(serializationTarget); + _xmlTextWriter.Flush(); + + var streamReader = new StreamReader(memoryStream, Encoding.UTF8, true); + memoryStream.Seek(0, SeekOrigin.Begin); + xml = streamReader.ReadToEnd(); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("SaveToXml failed", ex); + } + return xml; + } + + private void SetXmlTextWriterSettings() + { + _xmlTextWriter.Formatting = Formatting.Indented; + _xmlTextWriter.Indentation = 4; + } + + private void SaveNodesRecursive(ConnectionInfo node) + { + try + { + var nodeAsRoot = node as RootNodeInfo; + var nodeAsContainer = node as ContainerInfo; + if (nodeAsRoot != null) + { + SerializeRootNodeInfo(nodeAsRoot); + foreach (var child in nodeAsRoot.Children) + SaveNodesRecursive(child); + } + else if (nodeAsContainer != null) + { + SerializeContainerInfo(nodeAsContainer); + foreach (var child in nodeAsContainer.Children) + SaveNodesRecursive(child); + } + else + { + SerializeConnectionInfo(node); + } + _xmlTextWriter.WriteEndElement(); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SaveNode failed" + Environment.NewLine + ex.Message, true); + } + } + + private void SerializeRootNodeInfo(RootNodeInfo rootNodeInfo) + { + var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); + _xmlTextWriter.WriteStartElement("Connections"); // Do not localize + _xmlTextWriter.WriteAttributeString("Name", "", rootNodeInfo.Name); + _xmlTextWriter.WriteAttributeString("Export", "", Convert.ToString(Export)); + + if (Export) + { + _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsNotProtected", _password)); + } + else + { + if (rootNodeInfo.Password) + { + _password = rootNodeInfo.PasswordString.ConvertToSecureString(); + _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsProtected", _password)); + } + else + { + _xmlTextWriter.WriteAttributeString("Protected", "", cryptographyProvider.Encrypt("ThisIsNotProtected", _password)); + } + } + + _xmlTextWriter.WriteAttributeString("ConfVersion", "", ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture)); + } + + private void SerializeContainerInfo(ContainerInfo containerInfo) + { + _xmlTextWriter.WriteStartElement("Node"); + _xmlTextWriter.WriteAttributeString("Name", "", containerInfo.Name); + _xmlTextWriter.WriteAttributeString("Type", "", containerInfo.GetTreeNodeType().ToString()); + _xmlTextWriter.WriteAttributeString("Expanded", "", containerInfo.IsExpanded.ToString()); + SaveConnectionFields(containerInfo); + } + + private void SerializeConnectionInfo(ConnectionInfo connectionInfo) + { + _xmlTextWriter.WriteStartElement("Node"); + _xmlTextWriter.WriteAttributeString("Name", "", connectionInfo.Name); + _xmlTextWriter.WriteAttributeString("Type", "", connectionInfo.GetTreeNodeType().ToString()); + SaveConnectionFields(connectionInfo); + } + + private void SaveConnectionFields(ConnectionInfo connectionInfo) + { + try + { + var cryptographyProvider = new LegacyRijndaelCryptographyProvider(); + _xmlTextWriter.WriteAttributeString("Descr", "", connectionInfo.Description); + _xmlTextWriter.WriteAttributeString("Icon", "", connectionInfo.Icon); + _xmlTextWriter.WriteAttributeString("Panel", "", connectionInfo.Panel); + + if (SaveSecurity.Username) + _xmlTextWriter.WriteAttributeString("Username", "", connectionInfo.Username); + else + _xmlTextWriter.WriteAttributeString("Username", "", ""); + + if (SaveSecurity.Domain) + _xmlTextWriter.WriteAttributeString("Domain", "", connectionInfo.Domain); + else + _xmlTextWriter.WriteAttributeString("Domain", "", ""); + + if (SaveSecurity.Password) + _xmlTextWriter.WriteAttributeString("Password", "", cryptographyProvider.Encrypt(connectionInfo.Password, _password)); + else + _xmlTextWriter.WriteAttributeString("Password", "", ""); + + _xmlTextWriter.WriteAttributeString("Hostname", "", connectionInfo.Hostname); + _xmlTextWriter.WriteAttributeString("Protocol", "", connectionInfo.Protocol.ToString()); + _xmlTextWriter.WriteAttributeString("PuttySession", "", connectionInfo.PuttySession); + _xmlTextWriter.WriteAttributeString("Port", "", Convert.ToString(connectionInfo.Port)); + _xmlTextWriter.WriteAttributeString("ConnectToConsole", "", Convert.ToString(connectionInfo.UseConsoleSession)); + _xmlTextWriter.WriteAttributeString("UseCredSsp", "", Convert.ToString(connectionInfo.UseCredSsp)); + _xmlTextWriter.WriteAttributeString("RenderingEngine", "", connectionInfo.RenderingEngine.ToString()); + _xmlTextWriter.WriteAttributeString("ICAEncryptionStrength", "", connectionInfo.ICAEncryptionStrength.ToString()); + _xmlTextWriter.WriteAttributeString("RDPAuthenticationLevel", "", connectionInfo.RDPAuthenticationLevel.ToString()); + _xmlTextWriter.WriteAttributeString("LoadBalanceInfo", "", connectionInfo.LoadBalanceInfo); + _xmlTextWriter.WriteAttributeString("Colors", "", connectionInfo.Colors.ToString()); + _xmlTextWriter.WriteAttributeString("Resolution", "", connectionInfo.Resolution.ToString()); + _xmlTextWriter.WriteAttributeString("AutomaticResize", "", Convert.ToString(connectionInfo.AutomaticResize)); + _xmlTextWriter.WriteAttributeString("DisplayWallpaper", "", Convert.ToString(connectionInfo.DisplayWallpaper)); + _xmlTextWriter.WriteAttributeString("DisplayThemes", "", Convert.ToString(connectionInfo.DisplayThemes)); + _xmlTextWriter.WriteAttributeString("EnableFontSmoothing", "", Convert.ToString(connectionInfo.EnableFontSmoothing)); + _xmlTextWriter.WriteAttributeString("EnableDesktopComposition", "", Convert.ToString(connectionInfo.EnableDesktopComposition)); + _xmlTextWriter.WriteAttributeString("CacheBitmaps", "", Convert.ToString(connectionInfo.CacheBitmaps)); + _xmlTextWriter.WriteAttributeString("RedirectDiskDrives", "", Convert.ToString(connectionInfo.RedirectDiskDrives)); + _xmlTextWriter.WriteAttributeString("RedirectPorts", "", Convert.ToString(connectionInfo.RedirectPorts)); + _xmlTextWriter.WriteAttributeString("RedirectPrinters", "", Convert.ToString(connectionInfo.RedirectPrinters)); + _xmlTextWriter.WriteAttributeString("RedirectSmartCards", "", Convert.ToString(connectionInfo.RedirectSmartCards)); + _xmlTextWriter.WriteAttributeString("RedirectSound", "", connectionInfo.RedirectSound.ToString()); + _xmlTextWriter.WriteAttributeString("RedirectKeys", "", Convert.ToString(connectionInfo.RedirectKeys)); + + if (connectionInfo.OpenConnections.Count > 0) + _xmlTextWriter.WriteAttributeString("Connected", "", Convert.ToString(true)); + else + _xmlTextWriter.WriteAttributeString("Connected", "", Convert.ToString(false)); + + _xmlTextWriter.WriteAttributeString("PreExtApp", "", connectionInfo.PreExtApp); + _xmlTextWriter.WriteAttributeString("PostExtApp", "", connectionInfo.PostExtApp); + _xmlTextWriter.WriteAttributeString("MacAddress", "", connectionInfo.MacAddress); + _xmlTextWriter.WriteAttributeString("UserField", "", connectionInfo.UserField); + _xmlTextWriter.WriteAttributeString("ExtApp", "", connectionInfo.ExtApp); + + _xmlTextWriter.WriteAttributeString("VNCCompression", "", connectionInfo.VNCCompression.ToString()); + _xmlTextWriter.WriteAttributeString("VNCEncoding", "", connectionInfo.VNCEncoding.ToString()); + _xmlTextWriter.WriteAttributeString("VNCAuthMode", "", connectionInfo.VNCAuthMode.ToString()); + _xmlTextWriter.WriteAttributeString("VNCProxyType", "", connectionInfo.VNCProxyType.ToString()); + _xmlTextWriter.WriteAttributeString("VNCProxyIP", "", connectionInfo.VNCProxyIP); + _xmlTextWriter.WriteAttributeString("VNCProxyPort", "", Convert.ToString(connectionInfo.VNCProxyPort)); + _xmlTextWriter.WriteAttributeString("VNCProxyUsername", "", connectionInfo.VNCProxyUsername); + _xmlTextWriter.WriteAttributeString("VNCProxyPassword", "", cryptographyProvider.Encrypt(connectionInfo.VNCProxyPassword, _password)); + _xmlTextWriter.WriteAttributeString("VNCColors", "", connectionInfo.VNCColors.ToString()); + _xmlTextWriter.WriteAttributeString("VNCSmartSizeMode", "", connectionInfo.VNCSmartSizeMode.ToString()); + _xmlTextWriter.WriteAttributeString("VNCViewOnly", "", Convert.ToString(connectionInfo.VNCViewOnly)); + + _xmlTextWriter.WriteAttributeString("RDGatewayUsageMethod", "", connectionInfo.RDGatewayUsageMethod.ToString()); + _xmlTextWriter.WriteAttributeString("RDGatewayHostname", "", connectionInfo.RDGatewayHostname); + _xmlTextWriter.WriteAttributeString("RDGatewayUseConnectionCredentials", "", connectionInfo.RDGatewayUseConnectionCredentials.ToString()); + + if (SaveSecurity.Username) + _xmlTextWriter.WriteAttributeString("RDGatewayUsername", "", connectionInfo.RDGatewayUsername); + else + _xmlTextWriter.WriteAttributeString("RDGatewayUsername", "", ""); + + if (SaveSecurity.Password) + _xmlTextWriter.WriteAttributeString("RDGatewayPassword", "", cryptographyProvider.Encrypt(connectionInfo.RDGatewayPassword, _password)); + else + _xmlTextWriter.WriteAttributeString("RDGatewayPassword", "", ""); + + if (SaveSecurity.Domain) + _xmlTextWriter.WriteAttributeString("RDGatewayDomain", "", connectionInfo.RDGatewayDomain); + else + _xmlTextWriter.WriteAttributeString("RDGatewayDomain", "", ""); + + if (SaveSecurity.Inheritance) + { + _xmlTextWriter.WriteAttributeString("InheritCacheBitmaps", "", Convert.ToString(connectionInfo.Inheritance.CacheBitmaps)); + _xmlTextWriter.WriteAttributeString("InheritColors", "", Convert.ToString(connectionInfo.Inheritance.Colors)); + _xmlTextWriter.WriteAttributeString("InheritDescription", "", Convert.ToString(connectionInfo.Inheritance.Description)); + _xmlTextWriter.WriteAttributeString("InheritDisplayThemes", "", Convert.ToString(connectionInfo.Inheritance.DisplayThemes)); + _xmlTextWriter.WriteAttributeString("InheritDisplayWallpaper", "", Convert.ToString(connectionInfo.Inheritance.DisplayWallpaper)); + _xmlTextWriter.WriteAttributeString("InheritEnableFontSmoothing", "", Convert.ToString(connectionInfo.Inheritance.EnableFontSmoothing)); + _xmlTextWriter.WriteAttributeString("InheritEnableDesktopComposition", "", Convert.ToString(connectionInfo.Inheritance.EnableDesktopComposition)); + _xmlTextWriter.WriteAttributeString("InheritDomain", "", Convert.ToString(connectionInfo.Inheritance.Domain)); + _xmlTextWriter.WriteAttributeString("InheritIcon", "", Convert.ToString(connectionInfo.Inheritance.Icon)); + _xmlTextWriter.WriteAttributeString("InheritPanel", "", Convert.ToString(connectionInfo.Inheritance.Panel)); + _xmlTextWriter.WriteAttributeString("InheritPassword", "", Convert.ToString(connectionInfo.Inheritance.Password)); + _xmlTextWriter.WriteAttributeString("InheritPort", "", Convert.ToString(connectionInfo.Inheritance.Port)); + _xmlTextWriter.WriteAttributeString("InheritProtocol", "", Convert.ToString(connectionInfo.Inheritance.Protocol)); + _xmlTextWriter.WriteAttributeString("InheritPuttySession", "", Convert.ToString(connectionInfo.Inheritance.PuttySession)); + _xmlTextWriter.WriteAttributeString("InheritRedirectDiskDrives", "", Convert.ToString(connectionInfo.Inheritance.RedirectDiskDrives)); + _xmlTextWriter.WriteAttributeString("InheritRedirectKeys", "", Convert.ToString(connectionInfo.Inheritance.RedirectKeys)); + _xmlTextWriter.WriteAttributeString("InheritRedirectPorts", "", Convert.ToString(connectionInfo.Inheritance.RedirectPorts)); + _xmlTextWriter.WriteAttributeString("InheritRedirectPrinters", "", Convert.ToString(connectionInfo.Inheritance.RedirectPrinters)); + _xmlTextWriter.WriteAttributeString("InheritRedirectSmartCards", "", Convert.ToString(connectionInfo.Inheritance.RedirectSmartCards)); + _xmlTextWriter.WriteAttributeString("InheritRedirectSound", "", Convert.ToString(connectionInfo.Inheritance.RedirectSound)); + _xmlTextWriter.WriteAttributeString("InheritResolution", "", Convert.ToString(connectionInfo.Inheritance.Resolution)); + _xmlTextWriter.WriteAttributeString("InheritAutomaticResize", "", Convert.ToString(connectionInfo.Inheritance.AutomaticResize)); + _xmlTextWriter.WriteAttributeString("InheritUseConsoleSession", "", Convert.ToString(connectionInfo.Inheritance.UseConsoleSession)); + _xmlTextWriter.WriteAttributeString("InheritUseCredSsp", "", Convert.ToString(connectionInfo.Inheritance.UseCredSsp)); + _xmlTextWriter.WriteAttributeString("InheritRenderingEngine", "", Convert.ToString(connectionInfo.Inheritance.RenderingEngine)); + _xmlTextWriter.WriteAttributeString("InheritUsername", "", Convert.ToString(connectionInfo.Inheritance.Username)); + _xmlTextWriter.WriteAttributeString("InheritICAEncryptionStrength", "", Convert.ToString(connectionInfo.Inheritance.ICAEncryptionStrength)); + _xmlTextWriter.WriteAttributeString("InheritRDPAuthenticationLevel", "", Convert.ToString(connectionInfo.Inheritance.RDPAuthenticationLevel)); + _xmlTextWriter.WriteAttributeString("InheritLoadBalanceInfo", "", Convert.ToString(connectionInfo.Inheritance.LoadBalanceInfo)); + _xmlTextWriter.WriteAttributeString("InheritPreExtApp", "", Convert.ToString(connectionInfo.Inheritance.PreExtApp)); + _xmlTextWriter.WriteAttributeString("InheritPostExtApp", "", Convert.ToString(connectionInfo.Inheritance.PostExtApp)); + _xmlTextWriter.WriteAttributeString("InheritMacAddress", "", Convert.ToString(connectionInfo.Inheritance.MacAddress)); + _xmlTextWriter.WriteAttributeString("InheritUserField", "", Convert.ToString(connectionInfo.Inheritance.UserField)); + _xmlTextWriter.WriteAttributeString("InheritExtApp", "", Convert.ToString(connectionInfo.Inheritance.ExtApp)); + _xmlTextWriter.WriteAttributeString("InheritVNCCompression", "", Convert.ToString(connectionInfo.Inheritance.VNCCompression)); + _xmlTextWriter.WriteAttributeString("InheritVNCEncoding", "", Convert.ToString(connectionInfo.Inheritance.VNCEncoding)); + _xmlTextWriter.WriteAttributeString("InheritVNCAuthMode", "", Convert.ToString(connectionInfo.Inheritance.VNCAuthMode)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyType", "", Convert.ToString(connectionInfo.Inheritance.VNCProxyType)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyIP", "", Convert.ToString(connectionInfo.Inheritance.VNCProxyIP)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyPort", "", Convert.ToString(connectionInfo.Inheritance.VNCProxyPort)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyUsername", "", Convert.ToString(connectionInfo.Inheritance.VNCProxyUsername)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyPassword", "", Convert.ToString(connectionInfo.Inheritance.VNCProxyPassword)); + _xmlTextWriter.WriteAttributeString("InheritVNCColors", "", Convert.ToString(connectionInfo.Inheritance.VNCColors)); + _xmlTextWriter.WriteAttributeString("InheritVNCSmartSizeMode", "", Convert.ToString(connectionInfo.Inheritance.VNCSmartSizeMode)); + _xmlTextWriter.WriteAttributeString("InheritVNCViewOnly", "", Convert.ToString(connectionInfo.Inheritance.VNCViewOnly)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsageMethod", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayUsageMethod)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayHostname", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayHostname)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayUseConnectionCredentials", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayUseConnectionCredentials)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsername", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayUsername)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayPassword", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayPassword)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayDomain", "", Convert.ToString(connectionInfo.Inheritance.RDGatewayDomain)); + } + else + { + _xmlTextWriter.WriteAttributeString("InheritCacheBitmaps", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritColors", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritDescription", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritDisplayThemes", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritDisplayWallpaper", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritEnableFontSmoothing", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritEnableDesktopComposition", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritDomain", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritIcon", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPanel", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPassword", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPort", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritProtocol", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPuttySession", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectDiskDrives", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectKeys", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectPorts", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectPrinters", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectSmartCards", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRedirectSound", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritResolution", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritAutomaticResize", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritUseConsoleSession", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritUseCredSsp", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRenderingEngine", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritUsername", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritICAEncryptionStrength", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDPAuthenticationLevel", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritLoadBalanceInfo", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPreExtApp", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritPostExtApp", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritMacAddress", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritUserField", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritExtApp", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCCompression", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCEncoding", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCAuthMode", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyType", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyIP", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyPort", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyUsername", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCProxyPassword", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCColors", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCSmartSizeMode", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritVNCViewOnly", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayHostname", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayUseConnectionCredentials", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayUsername", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayPassword", "", Convert.ToString(false)); + _xmlTextWriter.WriteAttributeString("InheritRDGatewayDomain", "", Convert.ToString(false)); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SaveConnectionFields failed" + Environment.NewLine + ex.Message, true); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs index 70a3150a0..2a55a2661 100644 --- a/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs +++ b/mRemoteV1/Config/Settings/LayoutSettingsLoader.cs @@ -22,9 +22,9 @@ namespace mRemoteNG.Config.Settings { try { - Windows.treePanel = null; - Windows.configPanel = null; - Windows.errorsPanel = null; + Windows.TreePanel = null; + Windows.ConfigPanel = null; + Windows.ErrorsPanel = null; while (_MainForm.pnlDock.Contents.Count > 0) { @@ -67,16 +67,16 @@ namespace mRemoteNG.Config.Settings try { if (persistString == typeof(ConfigWindow).ToString()) - return Windows.configPanel; + return Windows.ConfigPanel; if (persistString == typeof(ConnectionTreeWindow).ToString()) - return Windows.treePanel; + return Windows.TreePanel; if (persistString == typeof(ErrorAndInfoWindow).ToString()) - return Windows.errorsPanel; + return Windows.ErrorsPanel; if (persistString == typeof(ScreenshotManagerWindow).ToString()) - return Windows.screenshotPanel; + return Windows.ScreenshotPanel; } catch (Exception ex) { @@ -88,21 +88,20 @@ namespace mRemoteNG.Config.Settings public void CreatePanels() { - Windows.configForm = new ConfigWindow(Windows.configPanel); - Windows.configPanel = Windows.configForm; + Windows.ConfigForm = new ConfigWindow(Windows.ConfigPanel); + Windows.ConfigPanel = Windows.ConfigForm; - Windows.treeForm = new ConnectionTreeWindow(Windows.treePanel); - Windows.treePanel = Windows.treeForm; - ConnectionTree.TreeView = Windows.treeForm.tvConnections; + Windows.TreeForm = new ConnectionTreeWindow(Windows.TreePanel); + Windows.TreePanel = Windows.TreeForm; - Windows.errorsForm = new ErrorAndInfoWindow(Windows.errorsPanel); - Windows.errorsPanel = Windows.errorsForm; + Windows.ErrorsForm = new ErrorAndInfoWindow(Windows.ErrorsPanel); + Windows.ErrorsPanel = Windows.ErrorsForm; - Windows.screenshotForm = new ScreenshotManagerWindow(Windows.screenshotPanel); - Windows.screenshotPanel = Windows.screenshotForm; + Windows.ScreenshotForm = new ScreenshotManagerWindow(Windows.ScreenshotPanel); + Windows.ScreenshotPanel = Windows.ScreenshotForm; - Windows.updateForm = new UpdateWindow(Windows.updatePanel); - Windows.updatePanel = Windows.updateForm; + Windows.UpdateForm = new UpdateWindow(Windows.UpdatePanel); + Windows.UpdatePanel = Windows.UpdateForm; Windows.AnnouncementForm = new AnnouncementWindow(Windows.AnnouncementPanel); Windows.AnnouncementPanel = Windows.AnnouncementForm; diff --git a/mRemoteV1/Connection/AbstractConnectionInfoData.cs b/mRemoteV1/Connection/AbstractConnectionInfoData.cs new file mode 100644 index 000000000..f4212ad28 --- /dev/null +++ b/mRemoteV1/Connection/AbstractConnectionInfoData.cs @@ -0,0 +1,641 @@ +using System.Collections.Generic; +using System.ComponentModel; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.Http; +using mRemoteNG.Connection.Protocol.ICA; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Connection.Protocol.VNC; +using mRemoteNG.Tools; + + +namespace mRemoteNG.Connection +{ + public abstract class AbstractConnectionInfoData : INotifyPropertyChanged + { + #region Fields + private string _name; + private string _description; + private string _icon; + private string _panel; + + private string _hostname; + private string _username; + private string _password; + private string _domain; + + private ProtocolType _protocol; + private string _extApp; + private int _port; + private string _puttySession; + private ProtocolICA.EncryptionStrength _icaEncryption; + private bool _useConsoleSession; + private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel; + private string _loadBalanceInfo; + private HTTPBase.RenderingEngine _renderingEngine; + private bool _useCredSsp; + + private ProtocolRDP.RDGatewayUsageMethod _rdGatewayUsageMethod; + private string _rdGatewayHostname; + private ProtocolRDP.RDGatewayUseConnectionCredentials _rdGatewayUseConnectionCredentials; + private string _rdGatewayUsername; + private string _rdGatewayPassword; + private string _rdGatewayDomain; + + private ProtocolRDP.RDPResolutions _resolution; + private bool _automaticResize; + private ProtocolRDP.RDPColors _colors; + private bool _cacheBitmaps; + private bool _displayWallpaper; + private bool _displayThemes; + private bool _enableFontSmoothing; + private bool _enableDesktopComposition; + + private bool _redirectKeys; + private bool _redirectDiskDrives; + private bool _redirectPrinters; + private bool _redirectPorts; + private bool _redirectSmartCards; + private ProtocolRDP.RDPSounds _redirectSound; + + private string _preExtApp; + private string _postExtApp; + private string _macAddress; + private string _userField; + + private ProtocolVNC.Compression _vncCompression; + private ProtocolVNC.Encoding _vncEncoding; + private ProtocolVNC.AuthMode _vncAuthMode; + private ProtocolVNC.ProxyType _vncProxyType; + private string _vncProxyIp; + private int _vncProxyPort; + private string _vncProxyUsername; + private string _vncProxyPassword; + private ProtocolVNC.Colors _vncColors; + private ProtocolVNC.SmartSizeMode _vncSmartSizeMode; + private bool _vncViewOnly; + #endregion + + #region Properties + #region Display + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameName"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionName")] + public virtual string Name + { + get { return _name; } + set { SetField(ref _name, value, "Name"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameDescription"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDescription")] + public virtual string Description + { + get { return GetPropertyValue("Description", _description); } + set { SetField(ref _description, value, "Description"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), + TypeConverter(typeof(ConnectionIcon)), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameIcon"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionIcon")] + public virtual string Icon + { + get { return GetPropertyValue("Icon", _icon); } + set { SetField(ref _icon, value, "Icon"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), + LocalizedAttributes.LocalizedDisplayName("strPropertyNamePanel"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPanel")] + public virtual string Panel + { + get { return GetPropertyValue("Panel", _panel); } + set { SetField(ref _panel, value, "Panel"); } + } + #endregion + + #region Connection + [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameAddress"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAddress")] + public virtual string Hostname + { + get { return _hostname.Trim(); } + set { SetField(ref _hostname, value?.Trim(), "Hostname"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameUsername"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUsername")] + public virtual string Username + { + get { return GetPropertyValue("Username", _username); } + set { SetField(ref _username, value?.Trim(), "Username"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), + LocalizedAttributes.LocalizedDisplayName("strPropertyNamePassword"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPassword"), + PasswordPropertyText(true)] + public virtual string Password + { + get { return GetPropertyValue("Password", _password); } + set { SetField(ref _password, value, "Password"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameDomain"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDomain")] + public string Domain + { + get { return GetPropertyValue("Domain", _domain).Trim(); } + set { SetField(ref _domain, value?.Trim(), "Domain"); } + } + #endregion + + #region Protocol + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameProtocol"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionProtocol"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public virtual ProtocolType Protocol + { + get { return GetPropertyValue("Protocol", _protocol); } + set { SetField(ref _protocol, value, "Protocol"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalTool"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalTool"), + TypeConverter(typeof(ExternalToolsTypeConverter))] + public string ExtApp + { + get { return GetPropertyValue("ExtApp", _extApp); } + set { SetField(ref _extApp, value, "ExtApp"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNamePort"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPort")] + public virtual int Port + { + get { return GetPropertyValue("Port", _port); } + set { SetField(ref _port, value, "Port"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNamePuttySession"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPuttySession"), + TypeConverter(typeof(Config.Putty.PuttySessionsManager.SessionList))] + public virtual string PuttySession + { + get { return GetPropertyValue("PuttySession", _puttySession); } + set { SetField(ref _puttySession, value, "PuttySession"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncryptionStrength"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncryptionStrength"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolICA.EncryptionStrength ICAEncryptionStrength + { + get { return GetPropertyValue("ICAEncryptionStrength", _icaEncryption); } + set { SetField(ref _icaEncryption, value, "ICAEncryptionStrength"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseConsoleSession"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseConsoleSession"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool UseConsoleSession + { + get { return GetPropertyValue("UseConsoleSession", _useConsoleSession); } + set { SetField(ref _useConsoleSession, value, "UseConsoleSession"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationLevel"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationLevel"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.AuthenticationLevel RDPAuthenticationLevel + { + get { return GetPropertyValue("RDPAuthenticationLevel", _rdpAuthenticationLevel); } + set { SetField(ref _rdpAuthenticationLevel, value, "RDPAuthenticationLevel"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo")] + public string LoadBalanceInfo + { + get { return GetPropertyValue("LoadBalanceInfo", _loadBalanceInfo).Trim(); } + set { SetField(ref _loadBalanceInfo, value?.Trim(), "LoadBalanceInfo"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRenderingEngine"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRenderingEngine"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public HTTPBase.RenderingEngine RenderingEngine + { + get { return GetPropertyValue("RenderingEngine", _renderingEngine); } + set { SetField(ref _renderingEngine, value, "RenderingEngine"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseCredSsp"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseCredSsp"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool UseCredSsp + { + get { return GetPropertyValue("UseCredSsp", _useCredSsp); } + set { SetField(ref _useCredSsp, value, "UseCredSsp"); } + } + #endregion + + #region RD Gateway + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsageMethod"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsageMethod"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.RDGatewayUsageMethod RDGatewayUsageMethod + { + get { return GetPropertyValue("RDGatewayUsageMethod", _rdGatewayUsageMethod); } + set { SetField(ref _rdGatewayUsageMethod, value, "RDGatewayUsageMethod"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayHostname"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayHostname")] + public string RDGatewayHostname + { + get { return GetPropertyValue("RDGatewayHostname", _rdGatewayHostname).Trim(); } + set { SetField(ref _rdGatewayHostname, value?.Trim(), "RDGatewayHostname"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUseConnectionCredentials"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUseConnectionCredentials"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.RDGatewayUseConnectionCredentials RDGatewayUseConnectionCredentials + { + get { return GetPropertyValue("RDGatewayUseConnectionCredentials", _rdGatewayUseConnectionCredentials); } + set { SetField(ref _rdGatewayUseConnectionCredentials, value, "RDGatewayUseConnectionCredentials"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsername"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsername")] + public string RDGatewayUsername + { + get { return GetPropertyValue("RDGatewayUsername", _rdGatewayUsername).Trim(); } + set { SetField(ref _rdGatewayUsername, value?.Trim(), "RDGatewayUsername"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayPassword"), + LocalizedAttributes.LocalizedDescription("strPropertyNameRDGatewayPassword"), + PasswordPropertyText(true)] + public string RDGatewayPassword + { + get { return GetPropertyValue("RDGatewayPassword", _rdGatewayPassword); } + set { SetField(ref _rdGatewayPassword, value, "RDGatewayPassword"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayDomain"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayDomain")] + public string RDGatewayDomain + { + get { return GetPropertyValue("RDGatewayDomain", _rdGatewayDomain).Trim(); } + set { SetField(ref _rdGatewayDomain, value?.Trim(), "RDGatewayDomain"); } + } + #endregion + + #region Appearance + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameResolution"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionResolution"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.RDPResolutions Resolution + { + get { return GetPropertyValue("Resolution", _resolution); } + set { SetField(ref _resolution, value, "Resolution"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameAutomaticResize"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAutomaticResize"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool AutomaticResize + { + get { return GetPropertyValue("AutomaticResize", _automaticResize); } + set { SetField(ref _automaticResize, value, "AutomaticResize"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.RDPColors Colors + { + get { return GetPropertyValue("Colors", _colors); } + set { SetField(ref _colors, value, "Colors"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameCacheBitmaps"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCacheBitmaps"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool CacheBitmaps + { + get { return GetPropertyValue("CacheBitmaps", _cacheBitmaps); } + set { SetField(ref _cacheBitmaps, value, "CacheBitmaps"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayWallpaper"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayWallpaper"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool DisplayWallpaper + { + get { return GetPropertyValue("DisplayWallpaper", _displayWallpaper); } + set { SetField(ref _displayWallpaper, value, "DisplayWallpaper"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayThemes"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayThemes"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool DisplayThemes + { + get { return GetPropertyValue("DisplayThemes", _displayThemes); } + set { SetField(ref _displayThemes, value, "DisplayThemes"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableFontSmoothing"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableFontSmoothing"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool EnableFontSmoothing + { + get { return GetPropertyValue("EnableFontSmoothing", _enableFontSmoothing); } + set { SetField(ref _enableFontSmoothing, value, "EnableFontSmoothing"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableDesktopComposition"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableDesktopComposition"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool EnableDesktopComposition + { + get { return GetPropertyValue("EnableDesktopComposition", _enableDesktopComposition); } + set { SetField(ref _enableDesktopComposition, value, "EnableDesktopComposition"); } + } + #endregion + + #region Redirect + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectKeys"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectKeys"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool RedirectKeys + { + get { return GetPropertyValue("RedirectKeys", _redirectKeys); } + set { SetField(ref _redirectKeys, value, "RedirectKeys"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectDrives"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectDrives"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool RedirectDiskDrives + { + get { return GetPropertyValue("RedirectDiskDrives", _redirectDiskDrives); } + set { SetField(ref _redirectDiskDrives, value, "RedirectDiskDrives"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPrinters"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPrinters"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool RedirectPrinters + { + get { return GetPropertyValue("RedirectPrinters", _redirectPrinters); } + set { SetField(ref _redirectPrinters, value, "RedirectPrinters"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPorts"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPorts"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool RedirectPorts + { + get { return GetPropertyValue("RedirectPorts", _redirectPorts); } + set { SetField(ref _redirectPorts, value, "RedirectPorts"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSmartCards"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSmartCards"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool RedirectSmartCards + { + get { return GetPropertyValue("RedirectSmartCards", _redirectSmartCards); } + set { SetField(ref _redirectSmartCards, value, "RedirectSmartCards"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSounds"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSounds"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolRDP.RDPSounds RedirectSound + { + get { return GetPropertyValue("RedirectSound", _redirectSound); } + set { SetField(ref _redirectSound, value, "RedirectSound"); } + } + #endregion + + #region Misc + [Browsable(false)] + public string ConstantID { get; set; } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalToolBefore"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalToolBefore"), + TypeConverter(typeof(ExternalToolsTypeConverter))] + public virtual string PreExtApp + { + get { return GetPropertyValue("PreExtApp", _preExtApp); } + set { SetField(ref _preExtApp, value, "PreExtApp"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalToolAfter"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalToolAfter"), + TypeConverter(typeof(ExternalToolsTypeConverter))] + public virtual string PostExtApp + { + get { return GetPropertyValue("PostExtApp", _postExtApp); } + set { SetField(ref _postExtApp, value, "PostExtApp"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameMACAddress"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionMACAddress")] + public virtual string MacAddress + { + get { return GetPropertyValue("MacAddress", _macAddress); } + set { SetField(ref _macAddress, value, "MacAddress"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameUser1"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUser1")] + public virtual string UserField + { + get { return GetPropertyValue("UserField", _userField); } + set { SetField(ref _userField, value, "UserField"); } + } + #endregion + + #region VNC + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameCompression"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCompression"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.Compression VNCCompression + { + get { return GetPropertyValue("VNCCompression", _vncCompression); } + set { SetField(ref _vncCompression, value, "VNCCompression"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncoding"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncoding"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.Encoding VNCEncoding + { + get { return GetPropertyValue("VNCEncoding", _vncEncoding); } + set { SetField(ref _vncEncoding, value, "VNCEncoding"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationMode"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationMode"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.AuthMode VNCAuthMode + { + get { return GetPropertyValue("VNCAuthMode", _vncAuthMode); } + set { SetField(ref _vncAuthMode, value, "VNCAuthMode"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyType"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyType"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.ProxyType VNCProxyType + { + get { return GetPropertyValue("VNCProxyType", _vncProxyType); } + set { SetField(ref _vncProxyType, value, "VNCProxyType"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyAddress"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyAddress")] + public string VNCProxyIP + { + get { return GetPropertyValue("VNCProxyIP", _vncProxyIp); } + set { SetField(ref _vncProxyIp, value, "VNCProxyIP"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPort"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPort")] + public int VNCProxyPort + { + get { return GetPropertyValue("VNCProxyPort", _vncProxyPort); } + set { SetField(ref _vncProxyPort, value, "VNCProxyPort"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyUsername"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyUsername")] + public string VNCProxyUsername + { + get { return GetPropertyValue("VNCProxyUsername", _vncProxyUsername); } + set { SetField(ref _vncProxyUsername, value, "VNCProxyUsername"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPassword"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPassword"), + PasswordPropertyText(true)] + public string VNCProxyPassword + { + get { return GetPropertyValue("VNCProxyPassword", _vncProxyPassword); } + set { SetField(ref _vncProxyPassword, value, "VNCProxyPassword"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + Browsable(false), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.Colors VNCColors + { + get { return GetPropertyValue("VNCColors", _vncColors); } + set { SetField(ref _vncColors, value, "VNCColors"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameSmartSizeMode"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionSmartSizeMode"), + TypeConverter(typeof(MiscTools.EnumTypeConverter))] + public ProtocolVNC.SmartSizeMode VNCSmartSizeMode + { + get { return GetPropertyValue("VNCSmartSizeMode", _vncSmartSizeMode); } + set { SetField(ref _vncSmartSizeMode, value, "VNCSmartSizeMode"); } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameViewOnly"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionViewOnly"), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool VNCViewOnly + { + get { return GetPropertyValue("VNCViewOnly", _vncViewOnly); } + set { SetField(ref _vncViewOnly, value, "VNCViewOnly"); } + } + #endregion + #endregion + + protected virtual TPropertyType GetPropertyValue(string propertyName, TPropertyType value) + { + return (TPropertyType)GetType().GetProperty(propertyName).GetValue(this, null); + } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void RaisePropertyChangedEvent(object sender, PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(sender, new PropertyChangedEventArgs(args.PropertyName)); + } + + protected bool SetField(ref T field, T value, string propertyName = null) + { + if (EqualityComparer.Default.Equals(field, value)) return false; + field = value; + RaisePropertyChangedEvent(this, new PropertyChangedEventArgs(propertyName)); + return true; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Connection/ConnectionInfo.cs b/mRemoteV1/Connection/ConnectionInfo.cs index 5526a2814..4d7118769 100644 --- a/mRemoteV1/Connection/ConnectionInfo.cs +++ b/mRemoteV1/Connection/ConnectionInfo.cs @@ -17,599 +17,15 @@ using mRemoteNG.Connection.Protocol.Rlogin; using mRemoteNG.Container; using mRemoteNG.Connection.Protocol; using mRemoteNG.Messages; +using mRemoteNG.Tree; namespace mRemoteNG.Connection { [DefaultProperty("Name")] - public class ConnectionInfo : IParent, IInheritable - { - #region Private Properties - private string _description; - private string _icon; - private string _panel; - private string _hostname; - private string _username; - private string _password; - private string _domain; - private ProtocolType _protocol; - private string _extApp; - private int _port; - private string _puttySession; - private ProtocolICA.EncryptionStrength _icaEncryption; - private bool _useConsoleSession; - private ProtocolRDP.AuthenticationLevel _rdpAuthenticationLevel; - private string _loadBalanceInfo; - private HTTPBase.RenderingEngine _renderingEngine; - private bool _useCredSsp; - private ProtocolRDP.RDGatewayUsageMethod _rdGatewayUsageMethod; - private string _rdGatewayHostname; - private ProtocolRDP.RDGatewayUseConnectionCredentials _rdGatewayUseConnectionCredentials; - private string _rdGatewayUsername; - private string _rdGatewayPassword; - private string _rdGatewayDomain; - private ProtocolRDP.RDPResolutions _resolution; - private bool _automaticResize; - private ProtocolRDP.RDPColors _colors; - private bool _cacheBitmaps; - private bool _displayWallpaper; - private bool _displayThemes; - private bool _enableFontSmoothing; - private bool _enableDesktopComposition; - private bool _redirectKeys; - private bool _redirectDiskDrives; - private bool _redirectPrinters; - private bool _redirectPorts; - private bool _redirectSmartCards; - private ProtocolRDP.RDPSounds _redirectSound; - private string _preExtApp; - private string _postExtApp; - private string _macAddress; - private string _userField; - private ProtocolVNC.Compression _vncCompression; - private ProtocolVNC.Encoding _vncEncoding; - private ProtocolVNC.AuthMode _vncAuthMode; - private ProtocolVNC.ProxyType _vncProxyType; - private string _vncProxyIp; - private int _vncProxyPort; - private string _vncProxyUsername; - private string _vncProxyPassword; - private ProtocolVNC.Colors _vncColors; - private ProtocolVNC.SmartSizeMode _vncSmartSizeMode; - private bool _vncViewOnly; - #endregion - + public class ConnectionInfo : AbstractConnectionInfoData, IHasParent, IInheritable, IDisposable + { #region Public Properties - #region Display - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameName"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionName")] - public virtual string Name { get; set; } - - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameDescription"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDescription")] - public virtual string Description - { - get { return GetPropertyValue("Description", _description); } - set { _description = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), - TypeConverter(typeof(ConnectionIcon)), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameIcon"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionIcon")] - public virtual string Icon - { - get { return GetPropertyValue("Icon", _icon); } - set { _icon = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay", 1), - LocalizedAttributes.LocalizedDisplayName("strPropertyNamePanel"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPanel")] - public virtual string Panel - { - get { return GetPropertyValue("Panel", _panel); } - set { _panel = value; } - } - #endregion - #region Connection - [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameAddress"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAddress")] - public virtual string Hostname - { - get { return _hostname.Trim(); } - set { - _hostname = string.IsNullOrEmpty(value) ? string.Empty : value.Trim(); - } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameUsername"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUsername")] - public virtual string Username - { - get { return GetPropertyValue("Username", _username); } - set { _username = value.Trim(); } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), - LocalizedAttributes.LocalizedDisplayName("strPropertyNamePassword"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPassword"), - PasswordPropertyText(true)] - public virtual string Password - { - get { return GetPropertyValue("Password", _password); } - set { _password = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameDomain"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDomain")] - public string Domain - { - get { return GetPropertyValue("Domain", _domain).Trim(); } - set { _domain = value.Trim(); } - } - #endregion - #region Protocol - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameProtocol"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionProtocol"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public virtual ProtocolType Protocol - { - get { return GetPropertyValue("Protocol", _protocol); } - set { _protocol = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalTool"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalTool"), - TypeConverter(typeof(ExternalToolsTypeConverter))] - public string ExtApp - { - get { return GetPropertyValue("ExtApp", _extApp); } - set { _extApp = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNamePort"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPort")] - public virtual int Port - { - get { return GetPropertyValue("Port", _port); } - set { _port = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNamePuttySession"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionPuttySession"), - TypeConverter(typeof(Config.Putty.Sessions.SessionList))] - public virtual string PuttySession - { - get { return GetPropertyValue("PuttySession", _puttySession); } - set { _puttySession = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncryptionStrength"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncryptionStrength"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolICA.EncryptionStrength ICAEncryptionStrength - { - get { return GetPropertyValue("ICAEncryptionStrength", _icaEncryption); } - set { _icaEncryption = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseConsoleSession"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseConsoleSession"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool UseConsoleSession - { - get { return GetPropertyValue("UseConsoleSession", _useConsoleSession); } - set { _useConsoleSession = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationLevel"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationLevel"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.AuthenticationLevel RDPAuthenticationLevel - { - get { return GetPropertyValue("RDPAuthenticationLevel", _rdpAuthenticationLevel); } - set { _rdpAuthenticationLevel = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameLoadBalanceInfo"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionLoadBalanceInfo")] - public string LoadBalanceInfo - { - get { return GetPropertyValue("LoadBalanceInfo", _loadBalanceInfo).Trim(); } - set { _loadBalanceInfo = value.Trim(); } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRenderingEngine"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRenderingEngine"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public HTTPBase.RenderingEngine RenderingEngine - { - get { return GetPropertyValue("RenderingEngine", _renderingEngine); } - set { _renderingEngine = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryProtocol", 3), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameUseCredSsp"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUseCredSsp"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool UseCredSsp - { - get { return GetPropertyValue("UseCredSsp", _useCredSsp); } - set { _useCredSsp = value; } - } - #endregion - #region RD Gateway - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsageMethod"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsageMethod"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.RDGatewayUsageMethod RDGatewayUsageMethod - { - get { return GetPropertyValue("RDGatewayUsageMethod", _rdGatewayUsageMethod); } - set { _rdGatewayUsageMethod = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayHostname"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayHostname")] - public string RDGatewayHostname - { - get { return GetPropertyValue("RDGatewayHostname", _rdGatewayHostname).Trim(); } - set { _rdGatewayHostname = value.Trim(); } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUseConnectionCredentials"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUseConnectionCredentials"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.RDGatewayUseConnectionCredentials RDGatewayUseConnectionCredentials - { - get { return GetPropertyValue("RDGatewayUseConnectionCredentials", _rdGatewayUseConnectionCredentials); } - set { _rdGatewayUseConnectionCredentials = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayUsername"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayUsername")] - public string RDGatewayUsername - { - get { return GetPropertyValue("RDGatewayUsername", _rdGatewayUsername).Trim(); } - set { _rdGatewayUsername = value.Trim(); } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayPassword"), - LocalizedAttributes.LocalizedDescription("strPropertyNameRDGatewayPassword"), - PasswordPropertyText(true)] - public string RDGatewayPassword - { - get { return GetPropertyValue("RDGatewayPassword", _rdGatewayPassword); } - set { _rdGatewayPassword = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryGateway", 4), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRDGatewayDomain"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRDGatewayDomain")] - public string RDGatewayDomain - { - get { return GetPropertyValue("RDGatewayDomain", _rdGatewayDomain).Trim(); } - set { _rdGatewayDomain = value.Trim(); } - } - #endregion - #region Appearance - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameResolution"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionResolution"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.RDPResolutions Resolution - { - get { return GetPropertyValue("Resolution", _resolution); } - set { _resolution = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameAutomaticResize"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAutomaticResize"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool AutomaticResize - { - get { return GetPropertyValue("AutomaticResize", _automaticResize); } - set { _automaticResize = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.RDPColors Colors - { - get { return GetPropertyValue("Colors", _colors); } - set { _colors = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameCacheBitmaps"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCacheBitmaps"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool CacheBitmaps - { - get { return GetPropertyValue("CacheBitmaps", _cacheBitmaps); } - set { _cacheBitmaps = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayWallpaper"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayWallpaper"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool DisplayWallpaper - { - get { return GetPropertyValue("DisplayWallpaper", _displayWallpaper); } - set { _displayWallpaper = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameDisplayThemes"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionDisplayThemes"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool DisplayThemes - { - get { return GetPropertyValue("DisplayThemes", _displayThemes); } - set { _displayThemes = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableFontSmoothing"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableFontSmoothing"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool EnableFontSmoothing - { - get { return GetPropertyValue("EnableFontSmoothing", _enableFontSmoothing); } - set { _enableFontSmoothing = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameEnableDesktopComposition"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEnableDesktopComposition"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool EnableDesktopComposition - { - get { return GetPropertyValue("EnableDesktopComposition", _enableDesktopComposition); } - set { _enableDesktopComposition = value; } - } - #endregion - #region Redirect - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectKeys"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectKeys"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool RedirectKeys - { - get { return GetPropertyValue("RedirectKeys", _redirectKeys); } - set { _redirectKeys = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectDrives"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectDrives"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool RedirectDiskDrives - { - get { return GetPropertyValue("RedirectDiskDrives", _redirectDiskDrives); } - set { _redirectDiskDrives = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPrinters"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPrinters"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool RedirectPrinters - { - get { return GetPropertyValue("RedirectPrinters", _redirectPrinters); } - set { _redirectPrinters = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectPorts"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectPorts"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool RedirectPorts - { - get { return GetPropertyValue("RedirectPorts", _redirectPorts); } - set { _redirectPorts = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSmartCards"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSmartCards"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool RedirectSmartCards - { - get { return GetPropertyValue("RedirectSmartCards", _redirectSmartCards); } - set { _redirectSmartCards = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryRedirect", 6), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameRedirectSounds"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionRedirectSounds"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolRDP.RDPSounds RedirectSound - { - get { return GetPropertyValue("RedirectSound", _redirectSound); } - set { _redirectSound = value; } - } - #endregion - #region Misc - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalToolBefore"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalToolBefore"), - TypeConverter(typeof(ExternalToolsTypeConverter))] - public virtual string PreExtApp - { - get { return GetPropertyValue("PreExtApp", _preExtApp); } - set { _preExtApp = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameExternalToolAfter"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionExternalToolAfter"), - TypeConverter(typeof(ExternalToolsTypeConverter))] - public virtual string PostExtApp - { - get { return GetPropertyValue("PostExtApp", _postExtApp); } - set { _postExtApp = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameMACAddress"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionMACAddress")] - public virtual string MacAddress - { - get { return GetPropertyValue("MacAddress", _macAddress); } - set { _macAddress = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameUser1"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionUser1")] - public virtual string UserField - { - get { return GetPropertyValue("UserField", _userField); } - set { _userField = value; } - } - #endregion - #region VNC - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameCompression"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionCompression"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.Compression VNCCompression - { - get { return GetPropertyValue("VNCCompression", _vncCompression); } - set { _vncCompression = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameEncoding"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionEncoding"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.Encoding VNCEncoding - { - get { return GetPropertyValue("VNCEncoding", _vncEncoding); } - set { _vncEncoding = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryConnection", 2), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameAuthenticationMode"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionAuthenticationMode"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.AuthMode VNCAuthMode - { - get { return GetPropertyValue("VNCAuthMode", _vncAuthMode); } - set { _vncAuthMode = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyType"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyType"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.ProxyType VNCProxyType - { - get { return GetPropertyValue("VNCProxyType", _vncProxyType); } - set { _vncProxyType = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyAddress"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyAddress")] - public string VNCProxyIP - { - get { return GetPropertyValue("VNCProxyIP", _vncProxyIp); } - set { _vncProxyIp = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPort"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPort")] - public int VNCProxyPort - { - get { return GetPropertyValue("VNCProxyPort", _vncProxyPort); } - set { _vncProxyPort = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyUsername"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyUsername")] - public string VNCProxyUsername - { - get { return GetPropertyValue("VNCProxyUsername", _vncProxyUsername); } - set { _vncProxyUsername = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryMiscellaneous", 7), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameVNCProxyPassword"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionVNCProxyPassword"), - PasswordPropertyText(true)] - public string VNCProxyPassword - { - get { return GetPropertyValue("VNCProxyPassword", _vncProxyPassword); } - set { _vncProxyPassword = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - Browsable(false), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameColors"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionColors"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.Colors VNCColors - { - get { return GetPropertyValue("VNCColors", _vncColors); } - set { _vncColors = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameSmartSizeMode"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionSmartSizeMode"), - TypeConverter(typeof(MiscTools.EnumTypeConverter))] - public ProtocolVNC.SmartSizeMode VNCSmartSizeMode - { - get { return GetPropertyValue("VNCSmartSizeMode", _vncSmartSizeMode); } - set { _vncSmartSizeMode = value; } - } - - [LocalizedAttributes.LocalizedCategory("strCategoryAppearance", 5), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameViewOnly"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionViewOnly"), - TypeConverter(typeof(MiscTools.YesNoTypeConverter))] - public bool VNCViewOnly - { - get { return GetPropertyValue("VNCViewOnly", _vncViewOnly); } - set { _vncViewOnly = value; } - } - #endregion - #region Non-browsable public properties [Browsable(false)] public ConnectionInfoInheritance Inheritance { get; set; } @@ -623,14 +39,11 @@ namespace mRemoteNG.Connection public bool IsDefault { get; set; } [Browsable(false)] - public ContainerInfo Parent { get; set; } + public ContainerInfo Parent { get; internal set; } [Browsable(false)] public int PositionID { get; set; } - [Browsable(false)] - public string ConstantID { get; set; } - [Browsable(false)] public TreeNode TreeNode { get; set; } @@ -639,9 +52,7 @@ namespace mRemoteNG.Connection [Browsable(false)] public bool PleaseConnect { get; set; } - #endregion - #endregion #region Constructors public ConnectionInfo() @@ -661,16 +72,19 @@ namespace mRemoteNG.Connection public ConnectionInfo(ContainerInfo parent) : this() { IsContainer = true; - parent.Add(this); + parent.AddChild(this); } #endregion #region Public Methods - public virtual ConnectionInfo Copy() + public virtual ConnectionInfo Clone() { - var newConnectionInfo = (ConnectionInfo)MemberwiseClone(); + var newConnectionInfo = new ConnectionInfo(); + newConnectionInfo.CopyFrom(this); newConnectionInfo.ConstantID = MiscTools.CreateConstantID(); + newConnectionInfo.SetParent(Parent); newConnectionInfo.OpenConnections = new ProtocolList(); + newConnectionInfo.Inheritance = Inheritance.Clone(); return newConnectionInfo; } @@ -683,7 +97,12 @@ namespace mRemoteNG.Connection property.SetValue(this, remotePropertyValue, null); } } - + + public virtual TreeNodeType GetTreeNodeType() + { + return TreeNodeType.Connection; + } + public void SetDefaults() { if (Port == 0) @@ -708,7 +127,23 @@ namespace mRemoteNG.Connection var filteredProperties = properties.Where((prop) => !excludedPropertyNames.Contains(prop.Name)); return filteredProperties; } - #endregion + + public virtual void SetParent(ContainerInfo parent) + { + RemoveParent(); + parent?.AddChild(this); + } + + public void RemoveParent() + { + Parent?.RemoveChild(this); + } + + public virtual void Dispose() + { + RemoveParent(); + } + #endregion #region Public Enumerations [Flags()] @@ -725,7 +160,7 @@ namespace mRemoteNG.Connection #endregion #region Private Methods - private TPropertyType GetPropertyValue(string propertyName, TPropertyType value) + protected override TPropertyType GetPropertyValue(string propertyName, TPropertyType value) { return ShouldThisPropertyBeInherited(propertyName) ? GetInheritedPropertyValue(propertyName) : value; } @@ -798,87 +233,87 @@ namespace mRemoteNG.Connection private void SetTreeDisplayDefaults() { Name = Language.strNewConnection; - _description = Settings.Default.ConDefaultDescription; - _icon = Settings.Default.ConDefaultIcon; - _panel = Language.strGeneral; + Description = Settings.Default.ConDefaultDescription; + Icon = Settings.Default.ConDefaultIcon; + Panel = Language.strGeneral; } private void SetConnectionDefaults() { - _hostname = string.Empty; - _username = Settings.Default.ConDefaultUsername; - _password = Settings.Default.ConDefaultPassword; - _domain = Settings.Default.ConDefaultDomain; + Hostname = string.Empty; + Username = Settings.Default.ConDefaultUsername; + Password = Settings.Default.ConDefaultPassword; + Domain = Settings.Default.ConDefaultDomain; } private void SetProtocolDefaults() { - _protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), Settings.Default.ConDefaultProtocol); - _extApp = Settings.Default.ConDefaultExtApp; - _port = 0; - _puttySession = Settings.Default.ConDefaultPuttySession; - _icaEncryption = (ProtocolICA.EncryptionStrength) Enum.Parse(typeof(ProtocolICA.EncryptionStrength), Settings.Default.ConDefaultICAEncryptionStrength); - _useConsoleSession = Settings.Default.ConDefaultUseConsoleSession; - _rdpAuthenticationLevel = (ProtocolRDP.AuthenticationLevel) Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), Settings.Default.ConDefaultRDPAuthenticationLevel); - _loadBalanceInfo = Settings.Default.ConDefaultLoadBalanceInfo; - _renderingEngine = (HTTPBase.RenderingEngine) Enum.Parse(typeof(HTTPBase.RenderingEngine), Settings.Default.ConDefaultRenderingEngine); - _useCredSsp = Settings.Default.ConDefaultUseCredSsp; + Protocol = (ProtocolType)Enum.Parse(typeof(ProtocolType), Settings.Default.ConDefaultProtocol); + ExtApp = Settings.Default.ConDefaultExtApp; + Port = 0; + PuttySession = Settings.Default.ConDefaultPuttySession; + ICAEncryptionStrength = (ProtocolICA.EncryptionStrength) Enum.Parse(typeof(ProtocolICA.EncryptionStrength), Settings.Default.ConDefaultICAEncryptionStrength); + UseConsoleSession = Settings.Default.ConDefaultUseConsoleSession; + RDPAuthenticationLevel = (ProtocolRDP.AuthenticationLevel) Enum.Parse(typeof(ProtocolRDP.AuthenticationLevel), Settings.Default.ConDefaultRDPAuthenticationLevel); + LoadBalanceInfo = Settings.Default.ConDefaultLoadBalanceInfo; + RenderingEngine = (HTTPBase.RenderingEngine) Enum.Parse(typeof(HTTPBase.RenderingEngine), Settings.Default.ConDefaultRenderingEngine); + UseCredSsp = Settings.Default.ConDefaultUseCredSsp; } private void SetRdGatewayDefaults() { - _rdGatewayUsageMethod = (ProtocolRDP.RDGatewayUsageMethod) Enum.Parse(typeof(ProtocolRDP.RDGatewayUsageMethod), Settings.Default.ConDefaultRDGatewayUsageMethod); - _rdGatewayHostname = Settings.Default.ConDefaultRDGatewayHostname; - _rdGatewayUseConnectionCredentials = (ProtocolRDP.RDGatewayUseConnectionCredentials) Enum.Parse(typeof(ProtocolRDP.RDGatewayUseConnectionCredentials), Settings.Default.ConDefaultRDGatewayUseConnectionCredentials); ; - _rdGatewayUsername = Settings.Default.ConDefaultRDGatewayUsername; - _rdGatewayPassword = Settings.Default.ConDefaultRDGatewayPassword; - _rdGatewayDomain = Settings.Default.ConDefaultRDGatewayDomain; + RDGatewayUsageMethod = (ProtocolRDP.RDGatewayUsageMethod) Enum.Parse(typeof(ProtocolRDP.RDGatewayUsageMethod), Settings.Default.ConDefaultRDGatewayUsageMethod); + RDGatewayHostname = Settings.Default.ConDefaultRDGatewayHostname; + RDGatewayUseConnectionCredentials = (ProtocolRDP.RDGatewayUseConnectionCredentials) Enum.Parse(typeof(ProtocolRDP.RDGatewayUseConnectionCredentials), Settings.Default.ConDefaultRDGatewayUseConnectionCredentials); ; + RDGatewayUsername = Settings.Default.ConDefaultRDGatewayUsername; + RDGatewayPassword = Settings.Default.ConDefaultRDGatewayPassword; + RDGatewayDomain = Settings.Default.ConDefaultRDGatewayDomain; } private void SetAppearanceDefaults() { - _resolution = (ProtocolRDP.RDPResolutions) Enum.Parse(typeof(ProtocolRDP.RDPResolutions), Settings.Default.ConDefaultResolution); - _automaticResize = Settings.Default.ConDefaultAutomaticResize; - _colors = (ProtocolRDP.RDPColors) Enum.Parse(typeof(ProtocolRDP.RDPColors), Settings.Default.ConDefaultColors); - _cacheBitmaps = Settings.Default.ConDefaultCacheBitmaps; - _displayWallpaper = Settings.Default.ConDefaultDisplayWallpaper; - _displayThemes = Settings.Default.ConDefaultDisplayThemes; - _enableFontSmoothing = Settings.Default.ConDefaultEnableFontSmoothing; - _enableDesktopComposition = Settings.Default.ConDefaultEnableDesktopComposition; + Resolution = (ProtocolRDP.RDPResolutions) Enum.Parse(typeof(ProtocolRDP.RDPResolutions), Settings.Default.ConDefaultResolution); + AutomaticResize = Settings.Default.ConDefaultAutomaticResize; + Colors = (ProtocolRDP.RDPColors) Enum.Parse(typeof(ProtocolRDP.RDPColors), Settings.Default.ConDefaultColors); + CacheBitmaps = Settings.Default.ConDefaultCacheBitmaps; + DisplayWallpaper = Settings.Default.ConDefaultDisplayWallpaper; + DisplayThemes = Settings.Default.ConDefaultDisplayThemes; + EnableFontSmoothing = Settings.Default.ConDefaultEnableFontSmoothing; + EnableDesktopComposition = Settings.Default.ConDefaultEnableDesktopComposition; } private void SetRedirectDefaults() { - _redirectKeys = Settings.Default.ConDefaultRedirectKeys; - _redirectDiskDrives = Settings.Default.ConDefaultRedirectDiskDrives; - _redirectPrinters = Settings.Default.ConDefaultRedirectPrinters; - _redirectPorts = Settings.Default.ConDefaultRedirectPorts; - _redirectSmartCards = Settings.Default.ConDefaultRedirectSmartCards; - _redirectSound = (ProtocolRDP.RDPSounds) Enum.Parse(typeof(ProtocolRDP.RDPSounds), Settings.Default.ConDefaultRedirectSound); + RedirectKeys = Settings.Default.ConDefaultRedirectKeys; + RedirectDiskDrives = Settings.Default.ConDefaultRedirectDiskDrives; + RedirectPrinters = Settings.Default.ConDefaultRedirectPrinters; + RedirectPorts = Settings.Default.ConDefaultRedirectPorts; + RedirectSmartCards = Settings.Default.ConDefaultRedirectSmartCards; + RedirectSound = (ProtocolRDP.RDPSounds) Enum.Parse(typeof(ProtocolRDP.RDPSounds), Settings.Default.ConDefaultRedirectSound); } private void SetMiscDefaults() { ConstantID = MiscTools.CreateConstantID(); - _preExtApp = Settings.Default.ConDefaultPreExtApp; - _postExtApp = Settings.Default.ConDefaultPostExtApp; - _macAddress = Settings.Default.ConDefaultMacAddress; - _userField = Settings.Default.ConDefaultUserField; + PreExtApp = Settings.Default.ConDefaultPreExtApp; + PostExtApp = Settings.Default.ConDefaultPostExtApp; + MacAddress = Settings.Default.ConDefaultMacAddress; + UserField = Settings.Default.ConDefaultUserField; } private void SetVncDefaults() { - _vncCompression = (ProtocolVNC.Compression) Enum.Parse(typeof(ProtocolVNC.Compression), Settings.Default.ConDefaultVNCCompression); - _vncEncoding = (ProtocolVNC.Encoding) Enum.Parse(typeof(ProtocolVNC.Encoding), Settings.Default.ConDefaultVNCEncoding); - _vncAuthMode = (ProtocolVNC.AuthMode) Enum.Parse(typeof(ProtocolVNC.AuthMode), Settings.Default.ConDefaultVNCAuthMode); - _vncProxyType = (ProtocolVNC.ProxyType) Enum.Parse(typeof(ProtocolVNC.ProxyType), Settings.Default.ConDefaultVNCProxyType); - _vncProxyIp = Settings.Default.ConDefaultVNCProxyIP; - _vncProxyPort = Settings.Default.ConDefaultVNCProxyPort; - _vncProxyUsername = Settings.Default.ConDefaultVNCProxyUsername; - _vncProxyPassword = Settings.Default.ConDefaultVNCProxyPassword; - _vncColors = (ProtocolVNC.Colors) Enum.Parse(typeof(ProtocolVNC.Colors), Settings.Default.ConDefaultVNCColors); - _vncSmartSizeMode = (ProtocolVNC.SmartSizeMode) Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), Settings.Default.ConDefaultVNCSmartSizeMode); - _vncViewOnly = Settings.Default.ConDefaultVNCViewOnly; + VNCCompression = (ProtocolVNC.Compression) Enum.Parse(typeof(ProtocolVNC.Compression), Settings.Default.ConDefaultVNCCompression); + VNCEncoding = (ProtocolVNC.Encoding) Enum.Parse(typeof(ProtocolVNC.Encoding), Settings.Default.ConDefaultVNCEncoding); + VNCAuthMode = (ProtocolVNC.AuthMode) Enum.Parse(typeof(ProtocolVNC.AuthMode), Settings.Default.ConDefaultVNCAuthMode); + VNCProxyType = (ProtocolVNC.ProxyType) Enum.Parse(typeof(ProtocolVNC.ProxyType), Settings.Default.ConDefaultVNCProxyType); + VNCProxyIP = Settings.Default.ConDefaultVNCProxyIP; + VNCProxyPort = Settings.Default.ConDefaultVNCProxyPort; + VNCProxyUsername = Settings.Default.ConDefaultVNCProxyUsername; + VNCProxyPassword = Settings.Default.ConDefaultVNCProxyPassword; + VNCColors = (ProtocolVNC.Colors) Enum.Parse(typeof(ProtocolVNC.Colors), Settings.Default.ConDefaultVNCColors); + VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode) Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), Settings.Default.ConDefaultVNCSmartSizeMode); + VNCViewOnly = Settings.Default.ConDefaultVNCViewOnly; } private void SetNonBrowsablePropertiesDefaults() diff --git a/mRemoteV1/Connection/ConnectionInfoComparer.cs b/mRemoteV1/Connection/ConnectionInfoComparer.cs new file mode 100644 index 000000000..0783c2b1a --- /dev/null +++ b/mRemoteV1/Connection/ConnectionInfoComparer.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + + +namespace mRemoteNG.Connection +{ + public class ConnectionInfoComparer : IComparer where TProperty : IComparable + { + private readonly Func _sortExpression; + public ListSortDirection SortDirection { get; set; } = ListSortDirection.Ascending; + + public ConnectionInfoComparer(Func sortExpression) + { + _sortExpression = sortExpression; + } + + public int Compare(ConnectionInfo x, ConnectionInfo y) + { + return SortDirection == ListSortDirection.Ascending ? CompareAscending(x, y) : CompareDescending(x, y); + } + + private int CompareAscending(ConnectionInfo x, ConnectionInfo y) + { + return _sortExpression(x).CompareTo(_sortExpression(y)); + } + + private int CompareDescending(ConnectionInfo x, ConnectionInfo y) + { + return _sortExpression(y).CompareTo(_sortExpression(x)); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Connection/ConnectionInfoInheritance.cs b/mRemoteV1/Connection/ConnectionInfoInheritance.cs index 4d7ac372c..058c374c6 100644 --- a/mRemoteV1/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteV1/Connection/ConnectionInfoInheritance.cs @@ -305,9 +305,11 @@ namespace mRemoteNG.Connection } - public ConnectionInfoInheritance Copy() + public ConnectionInfoInheritance Clone() { - return (ConnectionInfoInheritance)MemberwiseClone(); + var newInheritance = (ConnectionInfoInheritance) MemberwiseClone(); + newInheritance._tempInheritanceStorage = null; + return newInheritance; } public void EnableInheritance() @@ -330,7 +332,7 @@ namespace mRemoteNG.Connection private void StashInheritanceData() { - _tempInheritanceStorage = Copy(); + _tempInheritanceStorage = Clone(); } public void TurnOnInheritanceCompletely() diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs new file mode 100644 index 000000000..b4d8a06fd --- /dev/null +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -0,0 +1,297 @@ +using System; +using System.Windows.Forms; +using mRemoteNG.App; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Container; +using mRemoteNG.Messages; +using mRemoteNG.UI.Forms; +using mRemoteNG.UI.Window; +using TabPage = Crownwood.Magic.Controls.TabPage; + + +namespace mRemoteNG.Connection +{ + public static class ConnectionInitiator + { + public static void OpenConnection(ContainerInfo containerInfo) + { + OpenConnection(containerInfo, ConnectionInfo.Force.None); + } + + public static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force) + { + OpenConnection(containerInfo, force, null); + } + + public static void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force, Form conForm) + { + var children = containerInfo.Children; + if (children.Count == 0) return; + foreach (var child in children) + { + var childAsContainer = child as ContainerInfo; + if (childAsContainer != null) + OpenConnection(childAsContainer, force, conForm); + else + OpenConnection(child, force, conForm); + } + } + + public static void OpenConnection(ConnectionInfo connectionInfo) + { + try + { + OpenConnection(connectionInfo, ConnectionInfo.Force.None); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + } + } + + public static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force) + { + try + { + OpenConnection(connectionInfo, force, null); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + } + } + + public static void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force, Form conForm) + { + try + { + if (connectionInfo.Hostname == "" && connectionInfo.Protocol != ProtocolType.IntApp) + { + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strConnectionOpenFailedNoHostname); + return; + } + + StartPreConnectionExternalApp(connectionInfo); + + if ((force & ConnectionInfo.Force.DoNotJump) != ConnectionInfo.Force.DoNotJump) + { + if (SwitchToOpenConnection(connectionInfo)) + return; + } + + var protocolFactory = new ProtocolFactory(); + var newProtocol = protocolFactory.CreateProtocol(connectionInfo); + + var connectionPanel = SetConnectionPanel(connectionInfo, force); + var connectionForm = SetConnectionForm(conForm, connectionPanel); + var connectionContainer = SetConnectionContainer(connectionInfo, connectionForm); + SetConnectionFormEventHandlers(newProtocol, connectionForm); + SetConnectionEventHandlers(newProtocol); + BuildConnectionInterfaceController(connectionInfo, newProtocol, connectionContainer); + + newProtocol.Force = force; + + if (newProtocol.Initialize() == false) + { + newProtocol.Close(); + return; + } + + if (newProtocol.Connect() == false) + { + newProtocol.Close(); + return; + } + + connectionInfo.OpenConnections.Add(newProtocol); + frmMain.Default.SelectedConnection = connectionInfo; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionOpenFailed + Environment.NewLine + ex.Message); + } + } + + private static void StartPreConnectionExternalApp(ConnectionInfo connectionInfo) + { + if (connectionInfo.PreExtApp != "") + { + var extA = Runtime.GetExtAppByName(connectionInfo.PreExtApp); + extA?.Start(connectionInfo); + } + } + + public static bool SwitchToOpenConnection(ConnectionInfo nCi) + { + var IC = FindConnectionContainer(nCi); + if (IC != null) + { + var connectionWindow = (ConnectionWindow)IC.FindForm(); + connectionWindow?.Focus(); + var findForm = (ConnectionWindow)IC.FindForm(); + findForm?.Show(frmMain.Default.pnlDock); + var tabPage = (TabPage)IC.Parent; + tabPage.Selected = true; + return true; + } + return false; + } + + private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo) + { + if (connectionInfo.OpenConnections.Count > 0) + { + for (int i = 0; i <= Runtime.WindowList.Count - 1; i++) + { + if (Runtime.WindowList[i] is ConnectionWindow) + { + var connectionWindow = (ConnectionWindow)Runtime.WindowList[i]; + if (connectionWindow.TabController != null) + { + foreach (TabPage t in connectionWindow.TabController.TabPages) + { + if (t.Controls[0] != null && t.Controls[0] is InterfaceControl) + { + var IC = (InterfaceControl)t.Controls[0]; + if (IC.Info == connectionInfo) + { + return IC; + } + } + } + } + } + } + } + return null; + } + + private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force Force) + { + string connectionPanel = ""; + if (connectionInfo.Panel == "" || (Force & ConnectionInfo.Force.OverridePanel) == ConnectionInfo.Force.OverridePanel | Settings.Default.AlwaysShowPanelSelectionDlg) + { + frmChoosePanel frmPnl = new frmChoosePanel(); + if (frmPnl.ShowDialog() == DialogResult.OK) + { + connectionPanel = frmPnl.Panel; + } + } + else + { + connectionPanel = connectionInfo.Panel; + } + return connectionPanel; + } + + private static Form SetConnectionForm(Form conForm, string connectionPanel) + { + var connectionForm = conForm ?? Runtime.WindowList.FromString(connectionPanel); + + if (connectionForm == null) + connectionForm = Runtime.AddPanel(connectionPanel); + else + ((ConnectionWindow)connectionForm).Show(frmMain.Default.pnlDock); + + connectionForm.Focus(); + return connectionForm; + } + + private static Control SetConnectionContainer(ConnectionInfo connectionInfo, Form connectionForm) + { + Control connectionContainer = ((ConnectionWindow)connectionForm).AddConnectionTab(connectionInfo); + + if (connectionInfo.Protocol == ProtocolType.IntApp) + { + if (Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon != null) + ((TabPage)connectionContainer).Icon = Runtime.GetExtAppByName(connectionInfo.ExtApp).Icon; + } + return connectionContainer; + } + + private static void SetConnectionFormEventHandlers(ProtocolBase newProtocol, Form connectionForm) + { + newProtocol.Closed += ((ConnectionWindow)connectionForm).Prot_Event_Closed; + } + + private static void SetConnectionEventHandlers(ProtocolBase newProtocol) + { + newProtocol.Disconnected += Prot_Event_Disconnected; + newProtocol.Connected += Prot_Event_Connected; + newProtocol.Closed += Prot_Event_Closed; + newProtocol.ErrorOccured += Prot_Event_ErrorOccured; + } + + private static void BuildConnectionInterfaceController(ConnectionInfo connectionInfo, ProtocolBase newProtocol, Control connectionContainer) + { + newProtocol.InterfaceControl = new InterfaceControl(connectionContainer, newProtocol, connectionInfo); + } + + + + + private static void Prot_Event_Disconnected(object sender, string disconnectedMessage) + { + try + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strProtocolEventDisconnected, disconnectedMessage), true); + + var Prot = (ProtocolBase)sender; + if (Prot.InterfaceControl.Info.Protocol != ProtocolType.RDP) return; + var ReasonCode = disconnectedMessage.Split("\r\n".ToCharArray())[0]; + var desc = disconnectedMessage.Replace("\r\n", " "); + + if (Convert.ToInt32(ReasonCode) > 3) + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strRdpDisconnected + Environment.NewLine + desc); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.strProtocolEventDisconnectFailed, ex.Message), true); + } + } + + private static void Prot_Event_Closed(object sender) + { + try + { + var Prot = (ProtocolBase)sender; + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnenctionCloseEvent, true); + Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnenctionClosedByUser, Prot.InterfaceControl.Info.Hostname, Prot.InterfaceControl.Info.Protocol.ToString(), Environment.UserName)); + Prot.InterfaceControl.Info.OpenConnections.Remove(Prot); + + if (Prot.InterfaceControl.Info.PostExtApp == "") return; + var extA = Runtime.GetExtAppByName(Prot.InterfaceControl.Info.PostExtApp); + extA?.Start(Prot.InterfaceControl.Info); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnenctionCloseEventFailed + Environment.NewLine + ex.Message, true); + } + } + + private static void Prot_Event_Connected(object sender) + { + var prot = (ProtocolBase)sender; + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventConnected, true); + Runtime.MessageCollector.AddMessage(MessageClass.ReportMsg, string.Format(Language.strConnectionEventConnectedDetail, prot.InterfaceControl.Info.Hostname, prot.InterfaceControl.Info.Protocol, Environment.UserName, prot.InterfaceControl.Info.Description, prot.InterfaceControl.Info.UserField)); + } + + private static void Prot_Event_ErrorOccured(object sender, string errorMessage) + { + try + { + Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventErrorOccured, true); + var Prot = (ProtocolBase)sender; + + if (Prot.InterfaceControl.Info.Protocol != ProtocolType.RDP) return; + if (Convert.ToInt32(errorMessage) > -1) + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strConnectionRdpErrorDetail, errorMessage, ProtocolRDP.FatalErrors.GetError(errorMessage))); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionEventConnectionFailed + Environment.NewLine + ex.Message, true); + } + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Connection/ConnectionList.cs b/mRemoteV1/Connection/ConnectionList.cs deleted file mode 100644 index fb8329d4b..000000000 --- a/mRemoteV1/Connection/ConnectionList.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections; - - -namespace mRemoteNG.Connection -{ - public class ConnectionList : CollectionBase - { - public ConnectionInfo this[object Index] - { - get - { - if (Index is ConnectionInfo) - return (ConnectionInfo)Index; - else - return ((ConnectionInfo) (List[Convert.ToInt32(Index)])); - } - } - - public new int Count - { - get { return List.Count; } - } - - public ConnectionInfo Add(ConnectionInfo connectionInfo) - { - List.Add(connectionInfo); - return connectionInfo; - } - - public void AddRange(ConnectionInfo[] connectionInfoArray) - { - foreach (ConnectionInfo connectionInfo in connectionInfoArray) - { - List.Add(connectionInfo); - } - } - - public ConnectionInfo FindByConstantID(string id) - { - foreach (ConnectionInfo connectionInfo in List) - { - if (connectionInfo.ConstantID == id) - return connectionInfo; - } - - return null; - } - - public ConnectionList Copy() - { - try - { - return (ConnectionList)MemberwiseClone(); - } - catch (Exception) - { - } - - return null; - } - - public new void Clear() - { - List.Clear(); - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Connection/IHasParent.cs b/mRemoteV1/Connection/IHasParent.cs new file mode 100644 index 000000000..16275a0e7 --- /dev/null +++ b/mRemoteV1/Connection/IHasParent.cs @@ -0,0 +1,13 @@ +using mRemoteNG.Container; + +namespace mRemoteNG.Connection +{ + public interface IHasParent + { + ContainerInfo Parent { get; } + + void SetParent(ContainerInfo containerInfo); + + void RemoveParent(); + } +} \ No newline at end of file diff --git a/mRemoteV1/Connection/IParent.cs b/mRemoteV1/Connection/IParent.cs deleted file mode 100644 index 49145a197..000000000 --- a/mRemoteV1/Connection/IParent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using mRemoteNG.Container; - -namespace mRemoteNG.Connection -{ - public interface IParent - { - ContainerInfo Parent { get; set; } - } -} \ No newline at end of file diff --git a/mRemoteV1/Connection/InterfaceControl.cs b/mRemoteV1/Connection/InterfaceControl.cs index da50be2f2..9d4da95fa 100644 --- a/mRemoteV1/Connection/InterfaceControl.cs +++ b/mRemoteV1/Connection/InterfaceControl.cs @@ -9,36 +9,20 @@ namespace mRemoteNG.Connection { public partial class InterfaceControl { - #region Private Variables - private ProtocolBase _Protocol; - private ConnectionInfo _Info; - #endregion + public ProtocolBase Protocol { get; set; } + public ConnectionInfo Info { get; set; } - #region Public Properties - public ProtocolBase Protocol - { - get { return this._Protocol; } - set { this._Protocol = value; } - } - - public ConnectionInfo Info - { - get { return this._Info; } - set { this._Info = value; } - } - #endregion - - #region Constructors - public InterfaceControl(Control Parent, ProtocolBase Protocol, ConnectionInfo Info) + + public InterfaceControl(Control parent, ProtocolBase protocol, ConnectionInfo info) { try { - this._Protocol = Protocol; - this._Info = Info; - this.Parent = Parent; - this.Location = new Point(0, 0); - this.Size = this.Parent.Size; - this.Anchor = (System.Windows.Forms.AnchorStyles)(AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top); + Protocol = protocol; + Info = info; + Parent = parent; + Location = new Point(0, 0); + Size = Parent.Size; + Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top; InitializeComponent(); } catch (Exception ex) @@ -46,6 +30,5 @@ namespace mRemoteNG.Connection Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t create new InterfaceControl" + Environment.NewLine + ex.Message); } } - #endregion } } \ No newline at end of file diff --git a/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs b/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs index db93ef906..c9c09fc16 100644 --- a/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs +++ b/mRemoteV1/Connection/Protocol/ICA/Connection.Protocol.ICA.cs @@ -343,7 +343,7 @@ namespace mRemoteNG.Connection.Protocol.ICA #region Reconnect Stuff public void tmrReconnect_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { - bool srvReady = Scanner.IsPortOpen(_Info.Hostname, Convert.ToString(_Info.Port)); + bool srvReady = PortScanner.IsPortOpen(_Info.Hostname, Convert.ToString(_Info.Port)); ReconnectGroup.ServerReady = srvReady; diff --git a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs index 3bd9593a6..81013aeaa 100644 --- a/mRemoteV1/Connection/Protocol/IntegratedProgram.cs +++ b/mRemoteV1/Connection/Protocol/IntegratedProgram.cs @@ -40,7 +40,7 @@ namespace mRemoteNG.Connection.Protocol return false; } - ArgumentParser argParser = new ArgumentParser(_externalTool.ConnectionInfo); + ExternalToolArgumentParser argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo); _process = new Process(); _process.StartInfo.UseShellExecute = true; diff --git a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs index 377c1a05e..7f639ddb0 100644 --- a/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs +++ b/mRemoteV1/Connection/Protocol/RDP/Connection.Protocol.RDP.cs @@ -886,7 +886,7 @@ namespace mRemoteNG.Connection.Protocol.RDP #region Reconnect Stuff public void tmrReconnect_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { - bool srvReady = Scanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port)); + bool srvReady = PortScanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port)); ReconnectGroup.ServerReady = srvReady; diff --git a/mRemoteV1/Connection/PuttySessionInfo.cs b/mRemoteV1/Connection/PuttySessionInfo.cs index 4e9c15331..ee9dcd7a9 100644 --- a/mRemoteV1/Connection/PuttySessionInfo.cs +++ b/mRemoteV1/Connection/PuttySessionInfo.cs @@ -5,6 +5,7 @@ using System; using System.ComponentModel; using mRemoteNG.Connection.Protocol; using mRemoteNG.Root.PuttySessions; +using mRemoteNG.Tree; namespace mRemoteNG.Connection @@ -13,7 +14,7 @@ namespace mRemoteNG.Connection { #region Properties [Browsable(false)] - public PuttySessionsNodeInfo RootPuttySessionsInfo { get; set; } + public RootPuttySessionsNodeInfo RootRootPuttySessionsInfo { get; set; } [ReadOnly(true)] public override string PuttySession { get; set; } @@ -34,7 +35,7 @@ namespace mRemoteNG.Connection [ReadOnly(true), Browsable(false)] public override string Panel { - get { return RootPuttySessionsInfo.Panel; } + get { return Parent?.Panel; } set { } } @@ -82,15 +83,18 @@ namespace mRemoteNG.Connection } puttyProcess.SetControlText("Button", "&Cancel", "&Close"); puttyProcess.SetControlVisible("Button", "&Open", false); - puttyProcess.WaitForExit(); } catch (Exception ex) { Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorCouldNotLaunchPutty + Environment.NewLine + ex.Message); } } - - + + public override TreeNodeType GetTreeNodeType() + { + return TreeNodeType.PuttySession; + } + #region IComponent [Browsable(false)] public ISite Site diff --git a/mRemoteV1/Container/ContainerInfo.cs b/mRemoteV1/Container/ContainerInfo.cs index ef19ea43a..6cec738fe 100644 --- a/mRemoteV1/Container/ContainerInfo.cs +++ b/mRemoteV1/Container/ContainerInfo.cs @@ -1,11 +1,17 @@ +using System; using System.Collections.Generic; +using System.Collections.Specialized; using mRemoteNG.Connection; using System.ComponentModel; +using System.Linq; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Tools; +using mRemoteNG.Tree; namespace mRemoteNG.Container { [DefaultProperty("Name")] - public class ContainerInfo : ConnectionInfo + public class ContainerInfo : ConnectionInfo, INotifyCollectionChanged { [Browsable(false)] public List Children { get; set; } = new List(); @@ -13,48 +19,238 @@ namespace mRemoteNG.Container [Category(""), Browsable(false), ReadOnly(false), Bindable(false), DefaultValue(""), DesignOnly(false)] public bool IsExpanded { get; set; } + public ContainerInfo() { SetDefaults(); IsContainer = true; } - public void Add(ConnectionInfo newChildItem) + public override TreeNodeType GetTreeNodeType() { - newChildItem.Parent = this; - Children.Add(newChildItem); + return TreeNodeType.Container; } - public void AddRange(IEnumerable newChildren) + public bool HasChildren() + { + return Children.Count > 0; + } + + public void AddChild(ConnectionInfo newChildItem) + { + AddChildAt(newChildItem, Children.Count); + } + + public void AddChildAbove(ConnectionInfo newChildItem, ConnectionInfo reference) + { + var newChildIndex = Children.IndexOf(reference); + if (newChildIndex < 0) + newChildIndex = Children.Count; + AddChildAt(newChildItem, newChildIndex); + } + + public void AddChildBelow(ConnectionInfo newChildItem, ConnectionInfo reference) + { + var newChildIndex = Children.IndexOf(reference) + 1; + if (newChildIndex > Children.Count) + newChildIndex = 0; + AddChildAt(newChildItem, newChildIndex); + } + + public void AddChildAt(ConnectionInfo newChildItem, int index) + { + if (Children.Contains(newChildItem)) return; + newChildItem.Parent?.RemoveChild(newChildItem); + newChildItem.Parent = this; + Children.Insert(index, newChildItem); + SubscribeToChildEvents(newChildItem); + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newChildItem)); + } + + public void AddChildRange(IEnumerable newChildren) { foreach (var child in newChildren) { - Add(child); + AddChild(child); } } - public void Remove(ConnectionInfo removalTarget) + public void RemoveChild(ConnectionInfo removalTarget) { + if (!Children.Contains(removalTarget)) return; removalTarget.Parent = null; Children.Remove(removalTarget); + UnsubscribeToChildEvents(removalTarget); + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removalTarget)); } - public void RemoveRange(IEnumerable removalTargets) + public void RemoveChildRange(IEnumerable removalTargets) { foreach (var child in removalTargets) { - Remove(child); + RemoveChild(child); } } - public new ContainerInfo Copy() + public void SetChildPosition(ConnectionInfo child, int newIndex) + { + var originalIndex = Children.IndexOf(child); + if (originalIndex < 0 || originalIndex == newIndex || newIndex < 0) return; + Children.Remove(child); + if (newIndex > Children.Count) newIndex = Children.Count; + Children.Insert(newIndex, child); + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, child, newIndex, originalIndex)); + } + + public void SetChildAbove(ConnectionInfo childToPromote, ConnectionInfo reference) + { + var newIndex = GetNewChildIndexAboveReference(childToPromote, reference); + SetChildPosition(childToPromote, newIndex); + } + + private int GetNewChildIndexAboveReference(ConnectionInfo childToPromote, ConnectionInfo reference) + { + var originalIndex = Children.IndexOf(childToPromote); + var newIndex = Children.IndexOf(reference); + if (originalIndex < newIndex) + newIndex -= 1; + return newIndex < 0 ? 0 : newIndex; + } + + public void SetChildBelow(ConnectionInfo childToPromote, ConnectionInfo reference) + { + var newIndex = GetNewChildIndexBelowReference(childToPromote, reference); + SetChildPosition(childToPromote, newIndex); + } + + private int GetNewChildIndexBelowReference(ConnectionInfo childToPromote, ConnectionInfo reference) + { + var originalIndex = Children.IndexOf(childToPromote); + var newIndex = Children.IndexOf(reference); + if (originalIndex > newIndex) + newIndex += 1; + return newIndex < 0 ? 0 : newIndex; + } + + public void PromoteChild(ConnectionInfo child) + { + var originalIndex = Children.IndexOf(child); + SetChildPosition(child, originalIndex - 1); + } + + public void DemoteChild(ConnectionInfo child) + { + var originalIndex = Children.IndexOf(child); + SetChildPosition(child, originalIndex + 1); + } + + public void Sort(ListSortDirection sortDirection = ListSortDirection.Ascending) + { + SortOn(connectionInfo => connectionInfo.Name, sortDirection); + } + + public void SortOn(Func propertyToCompare, ListSortDirection sortDirection = ListSortDirection.Ascending) + where TProperty : IComparable + { + var connectionComparer = new ConnectionInfoComparer(propertyToCompare) + { + SortDirection = sortDirection + }; + Children.Sort(connectionComparer); + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + } + + public void SortRecursive(ListSortDirection sortDirection = ListSortDirection.Ascending) + { + SortOnRecursive(connectionInfo => connectionInfo.Name, sortDirection); + } + + public void SortOnRecursive(Func propertyToCompare, ListSortDirection sortDirection = ListSortDirection.Ascending) + where TProperty : IComparable + { + foreach (var child in Children.OfType()) + child.SortOnRecursive(propertyToCompare, sortDirection); + SortOn(propertyToCompare, sortDirection); + } + + public override void Dispose() + { + var tempChildList = Children.ToArray(); + foreach (var child in tempChildList) + child.Dispose(); + RemoveParent(); + } + + // Deep clone, recursive + public override ConnectionInfo Clone() { - return (ContainerInfo)MemberwiseClone(); + var newContainer = new ContainerInfo(); + newContainer.CopyFrom(this); + newContainer.ConstantID = MiscTools.CreateConstantID(); + newContainer.SetParent(Parent); + newContainer.OpenConnections = new ProtocolList(); + newContainer.Inheritance = Inheritance.Clone(); + foreach (var child in Children.ToArray()) + { + var newChild = child.Clone(); + newChild.RemoveParent(); + newContainer.AddChild(newChild); + } + return newContainer; } private new void SetDefaults() { + Name = "New Folder"; IsExpanded = true; } + + public IEnumerable GetRecursiveChildList() + { + var childList = new List(); + foreach (var child in Children) + { + childList.Add(child); + var childContainer = child as ContainerInfo; + if (childContainer != null) + childList.AddRange(GetRecursiveChildList(childContainer)); + } + return childList; + } + + private IEnumerable GetRecursiveChildList(ContainerInfo container) + { + var childList = new List(); + foreach (var child in container.Children) + { + childList.Add(child); + var childContainer = child as ContainerInfo; + if (childContainer != null) + childList.AddRange(GetRecursiveChildList(childContainer)); + } + return childList; + } + + protected virtual void SubscribeToChildEvents(ConnectionInfo child) + { + child.PropertyChanged += RaisePropertyChangedEvent; + var childAsContainer = child as ContainerInfo; + if (childAsContainer == null) return; + childAsContainer.CollectionChanged += RaiseCollectionChangedEvent; + } + + protected virtual void UnsubscribeToChildEvents(ConnectionInfo child) + { + child.PropertyChanged -= RaisePropertyChangedEvent; + var childAsContainer = child as ContainerInfo; + if (childAsContainer == null) return; + childAsContainer.CollectionChanged -= RaiseCollectionChangedEvent; + } + + public event NotifyCollectionChangedEventHandler CollectionChanged; + private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args) + { + CollectionChanged?.Invoke(sender, args); + } } } \ No newline at end of file diff --git a/mRemoteV1/Container/ContainerList.cs b/mRemoteV1/Container/ContainerList.cs deleted file mode 100644 index ac021387d..000000000 --- a/mRemoteV1/Container/ContainerList.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections; - - -namespace mRemoteNG.Container -{ - public class ContainerList : CollectionBase - { - public ContainerInfo this[object Index] - { - get - { - if (Index is ContainerInfo) - return (ContainerInfo)Index; - else - return ((ContainerInfo) (List[Convert.ToInt32(Index)])); - } - } - - public new int Count - { - get { return List.Count; } - } - - public ContainerList() : base() - { } - - #region Public Methods - public ContainerInfo Add(ContainerInfo containerInfo) - { - this.List.Add(containerInfo); - return containerInfo; - } - - public void AddRange(ContainerInfo[] cInfo) - { - foreach (ContainerInfo containerInfo in cInfo) - { - List.Add(containerInfo); - } - } - - public ContainerInfo FindByConstantID(string id) - { - foreach (ContainerInfo containerInfo in List) - { - if (containerInfo.ConstantID == id) - { - return containerInfo; - } - } - - return null; - } - - public ContainerList Copy() - { - try - { - return (ContainerList)this.MemberwiseClone(); - } - catch (Exception) - { - } - - return null; - } - - public new void Clear() - { - this.List.Clear(); - } - #endregion - } -} diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 94b0df436..106ad4ec1 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -3477,6 +3477,42 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to This node is already in this folder.. + /// + internal static string strNodeAlreadyInFolder { + get { + return ResourceManager.GetString("strNodeAlreadyInFolder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot drag node onto itself.. + /// + internal static string strNodeCannotDragOnSelf { + get { + return ResourceManager.GetString("strNodeCannotDragOnSelf", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot drag parent node onto child.. + /// + internal static string strNodeCannotDragParentOnChild { + get { + return ResourceManager.GetString("strNodeCannotDragParentOnChild", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This node is not draggable.. + /// + internal static string strNodeNotDraggable { + get { + return ResourceManager.GetString("strNodeNotDraggable", resourceCulture); + } + } + /// /// Looks up a localized string similar to No Ext. App specified.. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index afdc2012a..0b8f3a895 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2385,4 +2385,16 @@ mRemoteNG will now quit and begin with the installation. RDP Connection Timeout + + This node is already in this folder. + + + Cannot drag node onto itself. + + + Cannot drag parent node onto child. + + + This node is not draggable. + \ No newline at end of file diff --git a/mRemoteV1/Tools/ConnectionsTreeToMenuItemsConverter.cs b/mRemoteV1/Tools/ConnectionsTreeToMenuItemsConverter.cs new file mode 100644 index 000000000..0fb2db78f --- /dev/null +++ b/mRemoteV1/Tools/ConnectionsTreeToMenuItemsConverter.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Messages; +using mRemoteNG.Tree; + + +namespace mRemoteNG.Tools +{ + public class ConnectionsTreeToMenuItemsConverter + { + public MouseEventHandler MouseUpEventHandler { get; set; } + + + public IEnumerable CreateToolStripDropDownItems(ConnectionTreeModel connectionTreeModel) + { + var rootNodes = connectionTreeModel.RootNodes; + return CreateToolStripDropDownItems(rootNodes); + } + + public IEnumerable CreateToolStripDropDownItems(IEnumerable nodes) + { + var dropDownList = new List(); + try + { + dropDownList.AddRange(nodes.Select(CreateMenuItem)); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionMessage("frmMain.AddNodeToMenu() failed", ex, MessageClass.ErrorMsg, true); + } + return dropDownList; + } + + private void AddSubMenuNodes(IEnumerable nodes, ToolStripDropDownItem toolStripMenuItem) + { + foreach (var connectionInfo in nodes) + { + var newItem = CreateMenuItem(connectionInfo); + toolStripMenuItem.DropDownItems.Add(newItem); + } + } + + private ToolStripDropDownItem CreateMenuItem(ConnectionInfo node) + { + var menuItem = new ToolStripMenuItem + { + Text = node.Name, + Tag = node + }; + + var nodeAsContainer = node as ContainerInfo; + if (nodeAsContainer != null) + { + menuItem.Image = Resources.Folder; + menuItem.Tag = nodeAsContainer; + AddSubMenuNodes(nodeAsContainer.Children, menuItem); + } + else if (node.GetTreeNodeType() == TreeNodeType.PuttySession) + { + menuItem.Image = Resources.PuttySessions; + menuItem.Tag = node; + } + else if (node.GetTreeNodeType() == TreeNodeType.Connection) + { + menuItem.Image = Resources.Pause; + menuItem.Tag = node; + } + + menuItem.MouseUp += MouseUpEventHandler; + return menuItem; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tools/ExternalTool.cs b/mRemoteV1/Tools/ExternalTool.cs index 781c8fd64..9e25ae3c1 100644 --- a/mRemoteV1/Tools/ExternalTool.cs +++ b/mRemoteV1/Tools/ExternalTool.cs @@ -69,7 +69,7 @@ namespace mRemoteNG.Tools private void SetProcessProperties(Process process, ConnectionInfo startConnectionInfo) { - ArgumentParser argParser = new ArgumentParser(startConnectionInfo); + ExternalToolArgumentParser argParser = new ExternalToolArgumentParser(startConnectionInfo); process.StartInfo.UseShellExecute = true; process.StartInfo.FileName = argParser.ParseArguments(FileName); process.StartInfo.Arguments = argParser.ParseArguments(Arguments); @@ -80,7 +80,7 @@ namespace mRemoteNG.Tools try { ConnectionInfo newConnectionInfo = BuildConnectionInfoForIntegratedApp(); - Runtime.OpenConnection(newConnectionInfo); + ConnectionInitiator.OpenConnection(newConnectionInfo); } catch (Exception ex) { @@ -97,7 +97,7 @@ namespace mRemoteNG.Tools private ConnectionInfo GetAppropriateInstanceOfConnectionInfo() { - var newConnectionInfo = ConnectionInfo == null ? new ConnectionInfo() : ConnectionInfo.Copy(); + var newConnectionInfo = ConnectionInfo == null ? new ConnectionInfo() : ConnectionInfo.Clone(); return newConnectionInfo; } diff --git a/mRemoteV1/Tools/ArgumentParser.cs b/mRemoteV1/Tools/ExternalToolArgumentParser.cs similarity index 54% rename from mRemoteV1/Tools/ArgumentParser.cs rename to mRemoteV1/Tools/ExternalToolArgumentParser.cs index d0dff544c..b450b0a78 100644 --- a/mRemoteV1/Tools/ArgumentParser.cs +++ b/mRemoteV1/Tools/ExternalToolArgumentParser.cs @@ -4,47 +4,46 @@ using mRemoteNG.Connection; namespace mRemoteNG.Tools { - public class ArgumentParser + public class ExternalToolArgumentParser { - ConnectionInfo _connectionInfo; + private readonly ConnectionInfo _connectionInfo; - public ArgumentParser(ConnectionInfo connectionInfo) + public ExternalToolArgumentParser(ConnectionInfo connectionInfo) { _connectionInfo = connectionInfo; } public string ParseArguments(string input) { - int index = 0; - List replacements = new List(); + var replacements = BuildReplacementList(input); + var result = PerformReplacements(input, replacements); + return result; + } + private List BuildReplacementList(string input) + { + var index = 0; + var replacements = new List(); do { - int tokenStart = input.IndexOf("%", index, StringComparison.InvariantCulture); + var tokenStart = input.IndexOf("%", index, StringComparison.InvariantCulture); if (tokenStart == -1) - { break; - } - int tokenEnd = input.IndexOf("%", tokenStart + 1, StringComparison.InvariantCulture); + var tokenEnd = input.IndexOf("%", tokenStart + 1, StringComparison.InvariantCulture); if (tokenEnd == -1) - { break; - } - int tokenLength = tokenEnd - tokenStart + 1; - - int variableNameStart = tokenStart + 1; - int variableNameLength = tokenLength - 2; - - bool isEnvironmentVariable = false; - - string variableName = ""; + var tokenLength = tokenEnd - tokenStart + 1; + var variableNameStart = tokenStart + 1; + var variableNameLength = tokenLength - 2; + var isEnvironmentVariable = false; + var variableName = ""; if (tokenStart > 0) { - char tokenStartPrefix = input.Substring(tokenStart - 1, 1).ToCharArray()[0]; - char tokenEndPrefix = input.Substring(tokenEnd - 1, 1).ToCharArray()[0]; + var tokenStartPrefix = input.Substring(tokenStart - 1, 1).ToCharArray()[0]; + var tokenEndPrefix = input.Substring(tokenEnd - 1, 1).ToCharArray()[0]; if (tokenStartPrefix == '\\' && tokenEndPrefix == '\\') { @@ -74,19 +73,9 @@ namespace mRemoteNG.Tools } } - string token = input.Substring(tokenStart, tokenLength); + var token = input.Substring(tokenStart, tokenLength); - EscapeType escape = EscapeType.All; - string prefix = input.Substring(variableNameStart, 1); - switch (prefix) - { - case "-": - escape = EscapeType.ShellMetacharacters; - break; - case "!": - escape = EscapeType.None; - break; - } + var escape = DetermineEscapeType(token); if (escape != EscapeType.All) { @@ -103,13 +92,13 @@ namespace mRemoteNG.Tools variableName = input.Substring(variableNameStart, variableNameLength); - string replacementValue = token; + var replacementValue = token; if (!isEnvironmentVariable) { replacementValue = GetVariableReplacement(variableName, token); } - bool haveReplacement = false; + var haveReplacement = false; if (replacementValue != token) { @@ -144,67 +133,86 @@ namespace mRemoteNG.Tools index = tokenEnd; } } while (true); + return replacements; + } - string result = input; + private EscapeType DetermineEscapeType(string token) + { + var escape = EscapeType.All; + var prefix = token[1]; + switch (prefix) + { + case '-': + escape = EscapeType.ShellMetacharacters; + break; + case '!': + escape = EscapeType.None; + break; + } + return escape; + } + + private string GetVariableReplacement(string variable, string original) + { + var replacement = ""; + if (_connectionInfo == null) return replacement; + switch (variable.ToLowerInvariant()) + { + case "name": + replacement = _connectionInfo.Name; + break; + case "hostname": + replacement = _connectionInfo.Hostname; + break; + case "port": + replacement = Convert.ToString(_connectionInfo.Port); + break; + case "username": + replacement = _connectionInfo.Username; + break; + case "password": + replacement = _connectionInfo.Password; + break; + case "domain": + replacement = _connectionInfo.Domain; + break; + case "description": + replacement = _connectionInfo.Description; + break; + case "macaddress": + replacement = _connectionInfo.MacAddress; + break; + case "userfield": + replacement = _connectionInfo.UserField; + break; + default: + return original; + } + return replacement; + } + + private string PerformReplacements(string input, List replacements) + { + int index; + var result = input; for (index = result.Length; index >= 0; index--) { - foreach (Replacement replacement in replacements) + foreach (var replacement in replacements) { if (replacement.Start != index) { continue; } - string before = result.Substring(0, replacement.Start); - string after = result.Substring(replacement.Start + replacement.Length); + var before = result.Substring(0, replacement.Start); + var after = result.Substring(replacement.Start + replacement.Length); result = before + replacement.Value + after; } } return result; } - private string GetVariableReplacement(string variable, string original) - { - string replacement = ""; - if (_connectionInfo != null) - { - switch (variable.ToLowerInvariant()) - { - case "name": - replacement = _connectionInfo.Name; - break; - case "hostname": - replacement = _connectionInfo.Hostname; - break; - case "port": - replacement = Convert.ToString(_connectionInfo.Port); - break; - case "username": - replacement = _connectionInfo.Username; - break; - case "password": - replacement = _connectionInfo.Password; - break; - case "domain": - replacement = _connectionInfo.Domain; - break; - case "description": - replacement = _connectionInfo.Description; - break; - case "macaddress": - replacement = _connectionInfo.MacAddress; - break; - case "userfield": - replacement = _connectionInfo.UserField; - break; - default: - return original; - } - } - return replacement; - } - private enum EscapeType { All, @@ -214,31 +222,17 @@ namespace mRemoteNG.Tools private struct Replacement { - int _start; - int _length; - string _value; + public int Start { get; } - public int Start - { - get { return _start; } - set { _start = value; } - } - public int Length - { - get { return _length; } - set { _length = value; } - } - public string Value - { - get { return _value; } - set { _value = value; } - } + public int Length { get; } + + public string Value { get; } public Replacement(int start, int length, string value) { - _start = start; - _length = length; - _value = value; + Start = start; + Length = length; + Value = value; } } } diff --git a/mRemoteV1/Tools/MiscTools.cs b/mRemoteV1/Tools/MiscTools.cs index 9e9d9799e..5961a017d 100644 --- a/mRemoteV1/Tools/MiscTools.cs +++ b/mRemoteV1/Tools/MiscTools.cs @@ -67,24 +67,7 @@ namespace mRemoteNG.Tools return strDate; } - public static string PrepareForDB(string Text) - { - return ReplaceBooleanStringsWithNumbers(Text); - } - private static string ReplaceBooleanStringsWithNumbers(string Text) - { - Text = ReplaceTrueWith1(Text); - Text = ReplaceFalseWith0(Text); - return Text; - } - private static string ReplaceTrueWith1(string Text) - { - return Text.Replace("'True'", "1"); - } - private static string ReplaceFalseWith0(string Text) - { - return Text.Replace("'False'", "0"); - } + public static string PrepareValueForDB(string Text) { return Text.Replace("\'", "\'\'"); diff --git a/mRemoteV1/Tools/ScanHost.cs b/mRemoteV1/Tools/ScanHost.cs new file mode 100644 index 000000000..0947255c3 --- /dev/null +++ b/mRemoteV1/Tools/ScanHost.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections; +using System.Windows.Forms; +using mRemoteNG.App; +using mRemoteNG.Connection.Protocol.Http; +using mRemoteNG.Connection.Protocol.RDP; +using mRemoteNG.Connection.Protocol.Rlogin; +using mRemoteNG.Connection.Protocol.SSH; +using mRemoteNG.Connection.Protocol.Telnet; +using mRemoteNG.Connection.Protocol.VNC; +using mRemoteNG.Messages; + + +namespace mRemoteNG.Tools +{ + public class ScanHost + { + #region Properties + public static int SSHPort { get; set; } = (int)ProtocolSSH1.Defaults.Port; + public static int TelnetPort { get; set; } = (int)ProtocolTelnet.Defaults.Port; + public static int HTTPPort { get; set; } = (int)ProtocolHTTP.Defaults.Port; + public static int HTTPSPort { get; set; } = (int)ProtocolHTTPS.Defaults.Port; + public static int RloginPort { get; set; } = (int)ProtocolRlogin.Defaults.Port; + public static int RDPPort { get; set; } = (int)ProtocolRDP.Defaults.Port; + public static int VNCPort { get; set; } = (int)ProtocolVNC.Defaults.Port; + public ArrayList OpenPorts { get; set; } + public ArrayList ClosedPorts { get; set; } + public bool RDP { get; set; } + public bool VNC { get; set; } + public bool SSH { get; set; } + public bool Telnet { get; set; } + public bool Rlogin { get; set; } + public bool HTTP { get; set; } + public bool HTTPS { get; set; } + public string HostIp { get; set; } + public string HostName { get; set; } = ""; + public string HostNameWithoutDomain + { + get + { + if (string.IsNullOrEmpty(HostName) || HostName == HostIp) + { + return HostIp; + } + return HostName.Split('.')[0]; + } + } + #endregion + + #region Methods + public ScanHost(string host) + { + HostIp = host; + OpenPorts = new ArrayList(); + ClosedPorts = new ArrayList(); + } + + public override string ToString() + { + try + { + return "SSH: " + Convert.ToString(SSH) + " Telnet: " + Convert.ToString(Telnet) + " HTTP: " + Convert.ToString(HTTP) + " HTTPS: " + Convert.ToString(HTTPS) + " Rlogin: " + Convert.ToString(Rlogin) + " RDP: " + Convert.ToString(RDP) + " VNC: " + Convert.ToString(VNC); + } + catch (Exception) + { + Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "ToString failed (Tools.PortScan)", true); + return ""; + } + } + + public ListViewItem ToListViewItem() + { + try + { + var listViewItem = new ListViewItem + { + Tag = this, + Text = !string.IsNullOrEmpty(HostName) ? HostName : HostIp + }; + + listViewItem.SubItems.Add(BoolToYesNo(SSH)); + listViewItem.SubItems.Add(BoolToYesNo(Telnet)); + listViewItem.SubItems.Add(BoolToYesNo(HTTP)); + listViewItem.SubItems.Add(BoolToYesNo(HTTPS)); + listViewItem.SubItems.Add(BoolToYesNo(Rlogin)); + listViewItem.SubItems.Add(BoolToYesNo(RDP)); + listViewItem.SubItems.Add(BoolToYesNo(VNC)); + + var strOpen = ""; + var strClosed = ""; + + foreach (int p in OpenPorts) + { + strOpen += p + ", "; + } + + foreach (int p in ClosedPorts) + { + strClosed += p + ", "; + } + + listViewItem.SubItems.Add(strOpen.Substring(0, strOpen.Length > 0 ? strOpen.Length - 2 : strOpen.Length)); + listViewItem.SubItems.Add(strClosed.Substring(0, strClosed.Length > 0 ? strClosed.Length - 2 : strClosed.Length)); + + return listViewItem; + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("Tools.PortScan.ToListViewItem() failed.", ex); + return null; + } + } + + private static string BoolToYesNo(bool value) + { + return value ? Language.strYes : Language.strNo; + } + + public void SetAllProtocols(bool value) + { + VNC = value; + Telnet = value; + SSH = value; + Rlogin = value; + RDP = value; + HTTPS = value; + HTTP = value; + } + #endregion + } +} \ No newline at end of file diff --git a/mRemoteV1/Tools/Sorting/TreeNodeSorter.cs b/mRemoteV1/Tools/Sorting/TreeNodeSorter.cs deleted file mode 100644 index 946bdec49..000000000 --- a/mRemoteV1/Tools/Sorting/TreeNodeSorter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections; -using System.Windows.Forms; - -namespace mRemoteNG.Tools.Sorting -{ - public class TreeNodeSorter : IComparer - { - public SortOrder Sorting { get; set; } - - public TreeNodeSorter(SortOrder sortOrder = SortOrder.None) - { - Sorting = sortOrder; - } - - public int Compare(object x, object y) - { - TreeNode tx = (TreeNode)x; - TreeNode ty = (TreeNode)y; - - switch (Sorting) - { - case SortOrder.Ascending: - return String.CompareOrdinal(tx.Text, ty.Text); - case SortOrder.Descending: - return String.CompareOrdinal(ty.Text, tx.Text); - default: - return 0; - } - } - } -} \ No newline at end of file diff --git a/mRemoteV1/Tools/Tools.Controls.cs b/mRemoteV1/Tools/Tools.Controls.cs index 03a41879b..0eeebc794 100644 --- a/mRemoteV1/Tools/Tools.Controls.cs +++ b/mRemoteV1/Tools/Tools.Controls.cs @@ -1,6 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Windows.Forms; using mRemoteNG.App; +using mRemoteNG.Connection; using mRemoteNG.UI.Forms; @@ -8,52 +11,14 @@ namespace mRemoteNG.Tools { public class Controls { - public class ComboBoxItem - { - private string _Text; - public string Text - { - get { return this._Text; } - set { this._Text = value; } - } - - private object _Tag; - public object Tag - { - get - { - return this._Tag; - } - set - { - this._Tag = value; - } - } - - public ComboBoxItem(string Text, object Tag = null) - { - this._Text = Text; - if (Tag != null) - { - this._Tag = Tag; - } - } - - public override string ToString() - { - return this._Text; - } - } - public class NotificationAreaIcon { private NotifyIcon _nI; - private ContextMenuStrip _cMen; private ToolStripMenuItem _cMenCons; private ToolStripSeparator _cMenSep1; private ToolStripMenuItem _cMenExit; - + private bool _Disposed; public bool Disposed { @@ -66,111 +31,71 @@ namespace mRemoteNG.Tools _Disposed = value; } } - - - //Public Event MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) - //Public Event MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) - - + public NotificationAreaIcon() { try { - this._cMenCons = new ToolStripMenuItem(); - this._cMenCons.Text = Language.strConnections; - this._cMenCons.Image = Resources.Root; + _cMenCons = new ToolStripMenuItem(); + _cMenCons.Text = Language.strConnections; + _cMenCons.Image = Resources.Root; - this._cMenSep1 = new ToolStripSeparator(); + _cMenSep1 = new ToolStripSeparator(); - this._cMenExit = new ToolStripMenuItem(); - this._cMenExit.Text = Language.strMenuExit; - this._cMenExit.Click += cMenExit_Click; + _cMenExit = new ToolStripMenuItem(); + _cMenExit.Text = Language.strMenuExit; + _cMenExit.Click += cMenExit_Click; - this._cMen = new ContextMenuStrip(); - this._cMen.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)); - this._cMen.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this._cMen.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this._cMenCons, this._cMenSep1, this._cMenExit}); + _cMen = new ContextMenuStrip(); + _cMen.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)); + _cMen.RenderMode = ToolStripRenderMode.Professional; + _cMen.Items.AddRange(new ToolStripItem[] {_cMenCons, _cMenSep1, _cMenExit}); - this._nI = new NotifyIcon(); - this._nI.Text = "mRemote"; - this._nI.BalloonTipText = "mRemote"; - this._nI.Icon = Resources.mRemote_Icon; - this._nI.ContextMenuStrip = this._cMen; - this._nI.Visible = true; + _nI = new NotifyIcon(); + _nI.Text = "mRemote"; + _nI.BalloonTipText = "mRemote"; + _nI.Icon = Resources.mRemote_Icon; + _nI.ContextMenuStrip = _cMen; + _nI.Visible = true; - this._nI.MouseClick += nI_MouseClick; - this._nI.MouseDoubleClick += nI_MouseDoubleClick; + _nI.MouseClick += nI_MouseClick; + _nI.MouseDoubleClick += nI_MouseDoubleClick; } catch (Exception ex) { Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Creating new SysTrayIcon failed" + Environment.NewLine + ex.Message, true); } } - + public void Dispose() { try { - this._nI.Visible = false; - this._nI.Dispose(); - this._cMen.Dispose(); - this._Disposed = true; + _nI.Visible = false; + _nI.Dispose(); + _cMen.Dispose(); + _Disposed = true; } catch (Exception ex) { Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Disposing SysTrayIcon failed" + Environment.NewLine + ex.Message, true); } } - - private void nI_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) + + private void nI_MouseClick(object sender, MouseEventArgs e) { - if (e.Button == MouseButtons.Right) - { - this._cMenCons.DropDownItems.Clear(); - - foreach (TreeNode tNode in App.Windows.treeForm.tvConnections.Nodes) - { - AddNodeToMenu(tNode.Nodes, this._cMenCons); - } - } - } - - private void AddNodeToMenu(TreeNodeCollection tnc, ToolStripMenuItem menToolStrip) - { - try - { - foreach (TreeNode tNode in tnc) - { - ToolStripMenuItem tMenItem = new ToolStripMenuItem(); - tMenItem.Text = tNode.Text; - tMenItem.Tag = tNode; - - if (Tree.ConnectionTreeNode.GetNodeType(tNode) == Tree.TreeNodeType.Container) - { - tMenItem.Image = Resources.Folder; - tMenItem.Tag = tNode.Tag; - - menToolStrip.DropDownItems.Add(tMenItem); - AddNodeToMenu(tNode.Nodes, tMenItem); - } - else if (Tree.ConnectionTreeNode.GetNodeType(tNode) == Tree.TreeNodeType.Connection | Tree.ConnectionTreeNode.GetNodeType(tNode) == Tree.TreeNodeType.PuttySession) - { - tMenItem.Image = Windows.treeForm.imgListTree.Images[tNode.ImageIndex]; - tMenItem.Tag = tNode.Tag; - - menToolStrip.DropDownItems.Add(tMenItem); - } - - tMenItem.MouseUp += ConMenItem_MouseUp; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "AddNodeToMenu failed" + Environment.NewLine + ex.Message, true); - } - } - - private void nI_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e) + if (e.Button != MouseButtons.Right) return; + _cMenCons.DropDownItems.Clear(); + var menuItemsConverter = new ConnectionsTreeToMenuItemsConverter + { + MouseUpEventHandler = ConMenItem_MouseUp + }; + + ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionTreeModel).ToArray(); + _cMenCons.DropDownItems.AddRange(rootMenuItems); + } + + private void nI_MouseDoubleClick(object sender, MouseEventArgs e) { if (frmMain.Default.Visible == true) { @@ -181,41 +106,41 @@ namespace mRemoteNG.Tools ShowForm(); } } - + private void ShowForm() { frmMain.Default.Show(); frmMain.Default.WindowState = frmMain.Default.PreviousWindowState; - if (mRemoteNG.Settings.Default.ShowSystemTrayIcon == false) + if (Settings.Default.ShowSystemTrayIcon == false) { - App.Runtime.NotificationAreaIcon.Dispose(); - App.Runtime.NotificationAreaIcon = null; + Runtime.NotificationAreaIcon.Dispose(); + Runtime.NotificationAreaIcon = null; } } - + private void HideForm() { frmMain.Default.Hide(); frmMain.Default.PreviousWindowState = frmMain.Default.WindowState; } - - private void ConMenItem_MouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e) + + private void ConMenItem_MouseUp(Object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { - if (((System.Windows.Forms.Control)sender).Tag is Connection.ConnectionInfo) + if (((Control)sender).Tag is ConnectionInfo) { if (frmMain.Default.Visible == false) { ShowForm(); } - App.Runtime.OpenConnection((mRemoteNG.Connection.ConnectionInfo)((System.Windows.Forms.Control)sender).Tag); + ConnectionInitiator.OpenConnection((ConnectionInfo)((Control)sender).Tag); } } } - - private void cMenExit_Click(System.Object sender, System.EventArgs e) + + private void cMenExit_Click(Object sender, EventArgs e) { Shutdown.Quit(); } @@ -234,19 +159,6 @@ namespace mRemoteNG.Tools return saveFileDialog; } - public static SaveFileDialog ConnectionsExportDialog() - { - SaveFileDialog saveFileDialog = new SaveFileDialog(); - saveFileDialog.CheckPathExists = true; - saveFileDialog.InitialDirectory = App.Info.ConnectionsFileInfo.DefaultConnectionsPath; - saveFileDialog.FileName = App.Info.ConnectionsFileInfo.DefaultConnectionsFile; - saveFileDialog.OverwritePrompt = true; - - saveFileDialog.Filter = Language.strFiltermRemoteXML + "|*.xml|" + Language.strFiltermRemoteCSV + "|*.csv|" + Language.strFiltervRD2008CSV + "|*.csv|" + Language.strFilterAll + "|*.*"; - - return saveFileDialog; - } - public static OpenFileDialog ConnectionsLoadDialog() { OpenFileDialog lDlg = new OpenFileDialog(); @@ -256,15 +168,5 @@ namespace mRemoteNG.Tools return lDlg; } - - public static OpenFileDialog ImportConnectionsRdpFileDialog() - { - OpenFileDialog openFileDialog = new OpenFileDialog(); - openFileDialog.CheckFileExists = true; - openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal); - openFileDialog.Filter = string.Join("|", new[] {Language.strFilterRDP, "*.rdp", Language.strFilterAll, "*.*"}); - openFileDialog.Multiselect = true; - return openFileDialog; - } } } \ No newline at end of file diff --git a/mRemoteV1/Tools/Tools.PortScan.cs b/mRemoteV1/Tools/Tools.PortScan.cs index 715cddbb4..90688a524 100644 --- a/mRemoteV1/Tools/Tools.PortScan.cs +++ b/mRemoteV1/Tools/Tools.PortScan.cs @@ -1,162 +1,16 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Net.NetworkInformation; using System.Threading; -using System.Windows.Forms; using mRemoteNG.App; -using mRemoteNG.Connection.Protocol.Http; -using mRemoteNG.Connection.Protocol.RDP; -using mRemoteNG.Connection.Protocol.Rlogin; -using mRemoteNG.Connection.Protocol.SSH; -using mRemoteNG.Connection.Protocol.Telnet; -using mRemoteNG.Connection.Protocol.VNC; using mRemoteNG.Messages; + namespace mRemoteNG.Tools { - public class ScanHost - { - #region Private Variables - - #endregion - - #region Properties - public static int SSHPort { get; set; } = (int)ProtocolSSH1.Defaults.Port; - - public static int TelnetPort { get; set; } = (int)ProtocolTelnet.Defaults.Port; - - public static int HTTPPort { get; set; } = (int)ProtocolHTTP.Defaults.Port; - - public static int HTTPSPort { get; set; } = (int)ProtocolHTTPS.Defaults.Port; - - public static int RloginPort { get; set; } = (int)ProtocolRlogin.Defaults.Port; - - public static int RDPPort { get; set; } = (int)ProtocolRDP.Defaults.Port; - - public static int VNCPort { get; set; } = (int)ProtocolVNC.Defaults.Port; - - public string HostName { get; set; } = ""; - - public string HostNameWithoutDomain - { - get - { - if (string.IsNullOrEmpty(HostName) || HostName == HostIp) - { - return HostIp; - } - return HostName.Split('.')[0]; - } - } - - public string HostIp { get; set; } - - public ArrayList OpenPorts { get; set; } - - public ArrayList ClosedPorts { get; set; } - - public bool RDP { get; set; } - - public bool VNC { get; set; } - - public bool SSH { get; set; } - - public bool Telnet { get; set; } - - public bool Rlogin { get; set; } - - public bool HTTP { get; set; } - - public bool HTTPS { get; set; } - - #endregion - - #region Methods - public ScanHost(string host) - { - HostIp = host; - OpenPorts = new ArrayList(); - ClosedPorts = new ArrayList(); - } - - public override string ToString() - { - try - { - return "SSH: " + Convert.ToString(SSH) + " Telnet: " + Convert.ToString(Telnet) + " HTTP: " + Convert.ToString(HTTP) + " HTTPS: " + Convert.ToString(HTTPS) + " Rlogin: " + Convert.ToString(Rlogin) + " RDP: " + Convert.ToString(RDP) + " VNC: " + Convert.ToString(VNC); - } - catch (Exception) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "ToString failed (Tools.PortScan)", true); - return ""; - } - } - - public ListViewItem ToListViewItem() - { - try - { - ListViewItem listViewItem = new ListViewItem - { - Tag = this, - Text = !string.IsNullOrEmpty(HostName) ? HostName : HostIp - }; - - listViewItem.SubItems.Add(BoolToYesNo(SSH)); - listViewItem.SubItems.Add(BoolToYesNo(Telnet)); - listViewItem.SubItems.Add(BoolToYesNo(HTTP)); - listViewItem.SubItems.Add(BoolToYesNo(HTTPS)); - listViewItem.SubItems.Add(BoolToYesNo(Rlogin)); - listViewItem.SubItems.Add(BoolToYesNo(RDP)); - listViewItem.SubItems.Add(BoolToYesNo(VNC)); - - string strOpen = ""; - string strClosed = ""; - - foreach (int p in OpenPorts) - { - strOpen += p + ", "; - } - - foreach (int p in ClosedPorts) - { - strClosed += p + ", "; - } - - listViewItem.SubItems.Add(strOpen.Substring(0, strOpen.Length > 0 ? strOpen.Length - 2 : strOpen.Length)); - listViewItem.SubItems.Add(strClosed.Substring(0, strClosed.Length > 0 ? strClosed.Length - 2 : strClosed.Length)); - - return listViewItem; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("Tools.PortScan.ToListViewItem() failed.", ex); - return null; - } - } - - private static string BoolToYesNo(bool value) - { - return value ? Language.strYes : Language.strNo; - } - - public void SetAllProtocols(bool value) - { - VNC = value; - Telnet = value; - SSH = value; - Rlogin = value; - RDP = value; - HTTPS = value; - HTTP = value; - } - #endregion - } - - public class Scanner + public class PortScanner { #region Private Members private List _ipAddresses = new List(); @@ -167,7 +21,7 @@ namespace mRemoteNG.Tools #region Public Methods - public Scanner(IPAddress ipAddress1, IPAddress ipAddress2, int port1, int port2) + public PortScanner(IPAddress ipAddress1, IPAddress ipAddress2, int port1, int port2) { IPAddress ipAddressStart = IpAddressMin(ipAddress1, ipAddress2); IPAddress ipAddressEnd = IpAddressMax(ipAddress1, ipAddress2); diff --git a/mRemoteV1/Tree/ConnectionTree.cs b/mRemoteV1/Tree/ConnectionTree.cs deleted file mode 100644 index 018736d4d..000000000 --- a/mRemoteV1/Tree/ConnectionTree.cs +++ /dev/null @@ -1,379 +0,0 @@ -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Messages; -using mRemoteNG.Tools.Sorting; -using System; -using System.Collections.Generic; -using System.Windows.Forms; - -namespace mRemoteNG.Tree -{ - public static class ConnectionTree - { - private static TreeNode SetNodeToolTip_old_node; - private static TreeNode treeNodeToBeSelected; - private static TreeView _TreeView; - - public static TreeView TreeView - { - get { return _TreeView; } - set { _TreeView = value; } - } - - public static TreeNode SelectedNode - { - get - { - return _TreeView.SelectedNode; - } - set - { - treeNodeToBeSelected = value; - SelectNode(); - } - } - - public static void DeleteSelectedNode() - { - try - { - if (!SelectedNodeIsAValidDeletionTarget()) - return; - - if (ConnectionTreeNode.GetNodeType(SelectedNode) == TreeNodeType.Container) - { - if (ConnectionTreeNode.IsEmpty(SelectedNode)) - { - if (UserConfirmsEmptyFolderDeletion()) - SelectedNode.Remove(); - } - else - { - if (UserConfirmsNonEmptyFolderDeletion()) - { - TreeView.BeginUpdate(); - SelectedNode.Nodes.Clear(); - SelectedNode.Remove(); - TreeView.EndUpdate(); - } - } - } - else if (ConnectionTreeNode.GetNodeType(SelectedNode) == TreeNodeType.Connection) - { - if (UserConfirmsConnectionDeletion()) - SelectedNode.Remove(); - } - else - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "Tree item type is unknown so it cannot be deleted!"); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Deleting selected node failed" + Environment.NewLine + ex.Message, true); - } - } - - private static bool SelectedNodeIsAValidDeletionTarget() - { - bool validDeletionTarget = true; - if (SelectedNode == null) - validDeletionTarget = false; - else if (ConnectionTreeNode.GetNodeType(SelectedNode) == TreeNodeType.Root) - { - validDeletionTarget = false; - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, "The root item cannot be deleted!"); - } - return validDeletionTarget; - } - - private static bool UserConfirmsEmptyFolderDeletion() - { - string messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Text); - return PromptUser(messagePrompt); - } - - private static bool UserConfirmsNonEmptyFolderDeletion() - { - string messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Text); - return PromptUser(messagePrompt); - } - - private static bool UserConfirmsConnectionDeletion() - { - string messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Text); - return PromptUser(messagePrompt); - } - - private static bool PromptUser(string PromptMessage) - { - DialogResult msgBoxResponse = MessageBox.Show(PromptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - return (msgBoxResponse == DialogResult.Yes); - } - - public static void StartRenameSelectedNode() - { - SelectedNode?.BeginEdit(); - } - - public static void FinishRenameSelectedNode(string newName) - { - FinishRenameSelectedConnectionNode(newName); - FinishRenameSelectedContainerNode(newName); - } - - private static void FinishRenameSelectedConnectionNode(string newName) - { - ConnectionInfo connectionInfo = SelectedNode.Tag as ConnectionInfo; - if (connectionInfo != null) - ConnectionTreeNode.RenameNode(connectionInfo, newName); - } - - private static void FinishRenameSelectedContainerNode(string newName) - { - Container.ContainerInfo containerInfo = SelectedNode.Tag as Container.ContainerInfo; - if (containerInfo != null) - ConnectionTreeNode.RenameNode(containerInfo, newName); - } - - public static void SetNodeToolTip(MouseEventArgs e, ToolTip tTip) - { - try - { - if (!Settings.Default.ShowDescriptionTooltipsInTree) return; - //Find the node under the mouse. - TreeNode new_node = _TreeView.GetNodeAt(e.X, e.Y); - if (new_node == null || new_node.Equals(SetNodeToolTip_old_node)) - { - return; - } - SetNodeToolTip_old_node = new_node; - - //See if we have a node. - if (SetNodeToolTip_old_node == null) - { - tTip.SetToolTip(_TreeView, ""); - } - else - { - //Get this node's object data. - if (ConnectionTreeNode.GetNodeType(SetNodeToolTip_old_node) == TreeNodeType.Connection) - { - tTip.SetToolTip(_TreeView, ((ConnectionInfo) SetNodeToolTip_old_node.Tag).Description); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SetNodeToolTip failed" + Environment.NewLine + ex.Message, true); - } - } - - public static void ExpandAllNodes() - { - TreeView.BeginUpdate(); - TreeView.ExpandAll(); - TreeView.EndUpdate(); - } - - public static void CollapseAllNodes() - { - TreeView.BeginUpdate(); - foreach (TreeNode treeNode in TreeView.Nodes[0].Nodes) - { - treeNode.Collapse(false); - } - TreeView.EndUpdate(); - } - - public static void MoveNodeDown() - { - try - { - if (SelectedNode?.NextNode == null) return; - TreeView.BeginUpdate(); - TreeView.Sorted = false; - - TreeNode newNode = (TreeNode)SelectedNode.Clone(); - SelectedNode.Parent.Nodes.Insert(SelectedNode.Index + 2, newNode); - SelectedNode.Remove(); - SelectedNode = newNode; - - TreeView.EndUpdate(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "MoveNodeDown failed" + Environment.NewLine + ex.Message, true); - } - } - - public static void MoveNodeUp() - { - try - { - if (SelectedNode?.PrevNode == null) return; - TreeView.BeginUpdate(); - TreeView.Sorted = false; - - TreeNode newNode = (TreeNode)SelectedNode.Clone(); - SelectedNode.Parent.Nodes.Insert(SelectedNode.Index - 1, newNode); - SelectedNode.Remove(); - SelectedNode = newNode; - - TreeView.EndUpdate(); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "MoveNodeUp failed" + Environment.NewLine + ex.Message, true); - } - } - - public static void Sort(TreeNode treeNode, SortOrder sorting) - { - if (TreeView == null) - return; - - TreeView.BeginUpdate(); - - if (treeNode == null) - { - if (TreeView.Nodes.Count > 0) - treeNode = TreeView.Nodes[0]; - else - return; - } - else if (ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Connection) - { - treeNode = treeNode.Parent; - if (treeNode == null) - return; - } - - Sort(treeNode, new TreeNodeSorter(sorting)); - TreeView.EndUpdate(); - } - - private static void Sort(TreeNode treeNode, TreeNodeSorter nodeSorter) - { - // Adapted from http://www.codeproject.com/Tips/252234/ASP-NET-TreeView-Sort - foreach (TreeNode childNode in treeNode.Nodes) - { - Sort(childNode, nodeSorter); - } - - try - { - List sortedNodes = new List(); - TreeNode currentNode = null; - while (treeNode.Nodes.Count > 0) - { - foreach (TreeNode childNode in treeNode.Nodes) - { - if (currentNode == null || nodeSorter.Compare(childNode, currentNode) < 0) - { - currentNode = childNode; - } - } - if (currentNode != null) - { - treeNode.Nodes.Remove(currentNode); - sortedNodes.Add(currentNode); - } - currentNode = null; - } - - foreach (TreeNode childNode in sortedNodes) - { - treeNode.Nodes.Add(childNode); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Sort nodes failed" + Environment.NewLine + ex.Message, true); - } - } - - public static TreeNode Find(TreeNode treeNode, string searchFor) - { - - try - { - if (IsThisTheNodeWeAreSearchingFor(treeNode, searchFor)) - return treeNode; - - foreach (TreeNode childNode in treeNode.Nodes) - { - TreeNode tmpNode = Find(childNode, searchFor); - if (tmpNode != null) - { - return tmpNode; - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Find node failed" + Environment.NewLine + ex.Message, true); - } - - return null; - } - - private static bool IsThisTheNodeWeAreSearchingFor(TreeNode treeNode, string searchFor) - { - return treeNode.Text.ToLower().IndexOf(searchFor.ToLower(), StringComparison.Ordinal) + 1 > 0; - } - - public static TreeNode Find(TreeNode treeNode, ConnectionInfo conInfo) - { - try - { - if (treeNode.Tag == conInfo) - return treeNode; - - foreach (TreeNode childNode in treeNode.Nodes) - { - TreeNode tmpNode = Find(childNode, conInfo); - if (tmpNode != null) - return tmpNode; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Find node failed" + Environment.NewLine + ex.Message, true); - } - - return null; - } - - private delegate void ResetTreeDelegate(); - public static void ResetTree() - { - if (TreeView.InvokeRequired) - { - ResetTreeDelegate resetTreeDelegate = ResetTree; - Windows.treeForm.Invoke(resetTreeDelegate); - } - else - { - TreeView.BeginUpdate(); - TreeView.Nodes.Clear(); - TreeView.Nodes.Add(Language.strConnections); - TreeView.EndUpdate(); - } - } - - private delegate void SelectNodeCB(); - private static void SelectNode() - { - if (_TreeView.InvokeRequired) - { - SelectNodeCB d = SelectNode; - _TreeView.Invoke(d); - } - else - { - _TreeView.SelectedNode = treeNodeToBeSelected; - } - } - } -} diff --git a/mRemoteV1/Tree/ConnectionTreeDragAndDropHandler.cs b/mRemoteV1/Tree/ConnectionTreeDragAndDropHandler.cs new file mode 100644 index 000000000..2a8e865e9 --- /dev/null +++ b/mRemoteV1/Tree/ConnectionTreeDragAndDropHandler.cs @@ -0,0 +1,164 @@ +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using BrightIdeasSoftware; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Root.PuttySessions; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.Tree +{ + public class ConnectionTreeDragAndDropHandler + { + public Color DropAllowedFeedbackColor = Color.Green; + public Color DropDeniedFeedbackColor = Color.Red; + private string _infoMessage; + private Color _currentFeedbackColor; + private bool _enableFeedback; + + + public void HandleEvent_ModelDropped(object sender, ModelDropEventArgs e) + { + var dropTarget = e.TargetModel as ConnectionInfo; + if (dropTarget == null) return; + var dropSource = (ConnectionInfo)e.SourceModels[0]; + DropModel(dropSource, dropTarget, e.DropTargetLocation); + e.Handled = true; + Runtime.SaveConnectionsAsync(); + } + + public void DropModel(ConnectionInfo dropSource, ConnectionInfo dropTarget, DropTargetLocation dropTargetLocation) + { + if (dropTargetLocation == DropTargetLocation.Item) + DropModelOntoTarget(dropSource, dropTarget); + else if (dropTargetLocation == DropTargetLocation.AboveItem) + DropModelAboveTarget(dropSource, dropTarget); + else if (dropTargetLocation == DropTargetLocation.BelowItem) + DropModelBelowTarget(dropSource, dropTarget); + } + + private void DropModelOntoTarget(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + var dropTargetAsContainer = dropTarget as ContainerInfo; + if (dropTargetAsContainer == null) return; + dropSource.SetParent(dropTargetAsContainer); + } + + private void DropModelAboveTarget(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + if (!dropSource.Parent.Equals(dropTarget.Parent)) + dropTarget.Parent.AddChildAbove(dropSource, dropTarget); + else + dropTarget.Parent.SetChildAbove(dropSource, dropTarget); + } + + private void DropModelBelowTarget(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + if (!dropSource.Parent.Equals(dropTarget.Parent)) + dropTarget.Parent.AddChildBelow(dropSource, dropTarget); + else + dropTarget.Parent.SetChildBelow(dropSource, dropTarget); + } + + public void HandleEvent_ModelCanDrop(object sender, ModelDropEventArgs e) + { + _enableFeedback = true; + _currentFeedbackColor = DropDeniedFeedbackColor; + _infoMessage = null; + var dropSource = e.SourceModels.Cast().First(); + var dropTarget = e.TargetModel as ConnectionInfo; + + e.Effect = CanModelDrop(dropSource, dropTarget, e.DropTargetLocation); + e.InfoMessage = _infoMessage; + e.DropSink.EnableFeedback = _enableFeedback; + e.DropSink.FeedbackColor = _currentFeedbackColor; + e.Handled = true; + } + + public DragDropEffects CanModelDrop(ConnectionInfo dropSource, ConnectionInfo dropTarget, DropTargetLocation dropTargetLocation) + { + var dragDropEffect = DragDropEffects.None; + if (!NodeIsDraggable(dropSource)) + { + _infoMessage = Language.strNodeNotDraggable; + _enableFeedback = false; + } + else if (dropTargetLocation == DropTargetLocation.Item) + dragDropEffect = HandleCanDropOnItem(dropSource, dropTarget); + else if (dropTargetLocation == DropTargetLocation.AboveItem || dropTargetLocation == DropTargetLocation.BelowItem) + dragDropEffect = HandleCanDropBetweenItems(dropSource, dropTarget); + return dragDropEffect; + } + + private DragDropEffects HandleCanDropOnItem(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + var dragDropEffect = DragDropEffects.None; + if (dropTarget is ContainerInfo && !(dropTarget is RootPuttySessionsNodeInfo)) + { + if (!IsValidDrag(dropSource, dropTarget)) return dragDropEffect; + dragDropEffect = DragDropEffects.Move; + _currentFeedbackColor = DropAllowedFeedbackColor; + } + else + { + _enableFeedback = false; + } + return dragDropEffect; + } + + private DragDropEffects HandleCanDropBetweenItems(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + var dragDropEffect = DragDropEffects.None; + if (AncestorDraggingOntoChild(dropSource, dropTarget)) + _infoMessage = Language.strNodeCannotDragParentOnChild; + else if (dropTarget is PuttySessionInfo || dropTarget is RootNodeInfo) + _enableFeedback = false; + else + { + dragDropEffect = DragDropEffects.Move; + _currentFeedbackColor = DropAllowedFeedbackColor; + } + return dragDropEffect; + } + + private bool IsValidDrag(ConnectionInfo dropSource, ConnectionInfo dropTarget) + { + var validDrag = false; + if (NodeDraggingOntoSelf(dropSource, dropTarget)) + _infoMessage = Language.strNodeCannotDragOnSelf; + else if (AncestorDraggingOntoChild(dropSource, dropTarget)) + _infoMessage = Language.strNodeCannotDragParentOnChild; + else if (DraggingOntoCurrentParent(dropSource, dropTarget)) + _infoMessage = Language.strNodeAlreadyInFolder; + else + validDrag = true; + return validDrag; + } + + private bool NodeIsDraggable(ConnectionInfo node) + { + if (node == null || node is RootNodeInfo || node is PuttySessionInfo) return false; + return true; + } + + private bool NodeDraggingOntoSelf(ConnectionInfo source, ConnectionInfo target) + { + return source.Equals(target); + } + + private bool AncestorDraggingOntoChild(ConnectionInfo source, ConnectionInfo target) + { + var sourceAsContainer = source as ContainerInfo; + return sourceAsContainer != null && sourceAsContainer.GetRecursiveChildList().Contains(target); + } + + private bool DraggingOntoCurrentParent(ConnectionInfo source, ConnectionInfo target) + { + var targetAsContainer = target as ContainerInfo; + return targetAsContainer != null && targetAsContainer.Children.Contains(source); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/ConnectionTreeModel.cs b/mRemoteV1/Tree/ConnectionTreeModel.cs new file mode 100644 index 000000000..b36c75ecb --- /dev/null +++ b/mRemoteV1/Tree/ConnectionTreeModel.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using mRemoteNG.Connection; +using mRemoteNG.Container; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.Tree +{ + public class ConnectionTreeModel : INotifyCollectionChanged, INotifyPropertyChanged + { + public List RootNodes { get; } = new List(); + + public void AddRootNode(ContainerInfo rootNode) + { + if (RootNodes.Contains(rootNode)) return; + RootNodes.Add(rootNode); + rootNode.CollectionChanged += RaiseCollectionChangedEvent; + rootNode.PropertyChanged += RaisePropertyChangedEvent; + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, rootNode)); + } + + public void RemoveRootNode(ContainerInfo rootNode) + { + if (!RootNodes.Contains(rootNode)) return; + rootNode.CollectionChanged -= RaiseCollectionChangedEvent; + rootNode.PropertyChanged -= RaisePropertyChangedEvent; + RootNodes.Remove(rootNode); + RaiseCollectionChangedEvent(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, rootNode)); + } + + public IEnumerable GetRecursiveChildList() + { + var list = new List(); + foreach (var rootNode in RootNodes) + { + list.AddRange(GetRecursiveChildList(rootNode)); + } + return list; + } + + public IEnumerable GetRecursiveChildList(ContainerInfo container) + { + return container.GetRecursiveChildList(); + } + + public void RenameNode(ConnectionInfo connectionInfo, string newName) + { + if (newName == null || newName.Length <= 0) + return; + + connectionInfo.Name = newName; + if (Settings.Default.SetHostnameLikeDisplayName) + connectionInfo.Hostname = newName; + } + + public void DeleteNode(ConnectionInfo connectionInfo) + { + if (connectionInfo is RootNodeInfo) + return; + + connectionInfo?.Dispose(); + } + + public void CloneNode(ConnectionInfo connectionInfo) + { + connectionInfo.Clone(); + } + + public event NotifyCollectionChangedEventHandler CollectionChanged; + private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args) + { + CollectionChanged?.Invoke(sender, args); + } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void RaisePropertyChangedEvent(object sender, PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(sender, args); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/ConnectionTreeNode.cs b/mRemoteV1/Tree/ConnectionTreeNode.cs deleted file mode 100644 index a90b040fe..000000000 --- a/mRemoteV1/Tree/ConnectionTreeNode.cs +++ /dev/null @@ -1,278 +0,0 @@ -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Container; -using System; -using System.Windows.Forms; -using mRemoteNG.Messages; -using mRemoteNG.Root.PuttySessions; -using mRemoteNG.Tree.Root; - -namespace mRemoteNG.Tree -{ - public static class ConnectionTreeNode - { - #region Public Methods - public static string GetConstantID(TreeNode node) - { - if (GetNodeType(node) == TreeNodeType.Connection) - return ((ConnectionInfo) node.Tag).ConstantID; - if (GetNodeType(node) == TreeNodeType.Container) - return ((ContainerInfo) node.Tag).ConstantID; - - return null; - } - - public static TreeNode GetNodeFromPositionID(int id) - { - foreach (ConnectionInfo connection in Runtime.ConnectionList) - { - if (connection.PositionID == id) - { - if (connection.IsContainer) - return connection.Parent.TreeNode; - return connection.TreeNode; - } - } - - return null; - } - - public static TreeNode GetNodeFromConstantID(string id) - { - foreach (ConnectionInfo connectionInfo in Runtime.ConnectionList) - { - if (connectionInfo.ConstantID == id) - { - if (connectionInfo.IsContainer) - return connectionInfo.Parent.TreeNode; - return connectionInfo.TreeNode; - } - } - - return null; - } - - public static TreeNodeType GetNodeType(TreeNode treeNode) - { - try - { - if (treeNode?.Tag == null) - return TreeNodeType.None; - - if (treeNode.Tag is PuttySessionsNodeInfo) - return TreeNodeType.PuttyRoot; - if (treeNode.Tag is RootNodeInfo) - return TreeNodeType.Root; - if (treeNode.Tag is ContainerInfo) - return TreeNodeType.Container; - if (treeNode.Tag is PuttySessionInfo) - return TreeNodeType.PuttySession; - if (treeNode.Tag is ConnectionInfo) - return TreeNodeType.Connection; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t get node type" + Environment.NewLine + ex.Message, true); - } - - return TreeNodeType.None; - } - - public static TreeNodeType GetNodeTypeFromString(string str) - { - try - { - switch (str.ToLower()) - { - case "root": - return TreeNodeType.Root; - case "container": - return TreeNodeType.Container; - case "connection": - return TreeNodeType.Connection; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t get node type from string" + Environment.NewLine + ex.Message, true); - } - - return TreeNodeType.None; - } - - public static bool IsEmpty(TreeNode treeNode) - { - try - { - if (treeNode.Nodes.Count > 0) - return false; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "IsEmpty (Tree.Node) failed" + Environment.NewLine + ex.Message, true); - } - - return true; - } - - public static TreeNode AddNode(TreeNodeType nodeType, string name = null) - { - try - { - TreeNode treeNode = new TreeNode(); - string defaultName = ""; - - switch (nodeType) - { - case TreeNodeType.Connection: - case TreeNodeType.PuttySession: - defaultName = Language.strNewConnection; - treeNode.ImageIndex = (int)TreeImageType.ConnectionClosed; - treeNode.SelectedImageIndex = (int)TreeImageType.ConnectionClosed; - break; - case TreeNodeType.Container: - defaultName = Language.strNewFolder; - treeNode.ImageIndex = (int)TreeImageType.Container; - treeNode.SelectedImageIndex = (int)TreeImageType.Container; - break; - case TreeNodeType.Root: - defaultName = Language.strNewRoot; - treeNode.ImageIndex = (int)TreeImageType.Root; - treeNode.SelectedImageIndex = (int)TreeImageType.Root; - break; - } - - treeNode.Name = !string.IsNullOrEmpty(name) ? name : defaultName; - treeNode.Text = treeNode.Name; - - return treeNode; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "AddNode failed" + Environment.NewLine + ex.Message, true); - } - - return null; - } - - public static void CloneNode(TreeNode oldTreeNode, TreeNode parentNode = null) - { - try - { - if (GetNodeType(oldTreeNode) == TreeNodeType.Connection) - CloneConnectionNode(oldTreeNode, parentNode); - else if (GetNodeType(oldTreeNode) == TreeNodeType.Container) - CloneContainerNode(oldTreeNode, parentNode); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, string.Format(Language.strErrorCloneNodeFailed, ex.Message)); - } - } - - private static void CloneContainerNode(TreeNode oldTreeNode, TreeNode parentNode) - { - ContainerInfo oldContainerInfo = (ContainerInfo) oldTreeNode.Tag; - - ContainerInfo newContainerInfo = oldContainerInfo.Copy(); - ConnectionInfo newConnectionInfo = oldContainerInfo.Copy(); - newContainerInfo.CopyFrom(newConnectionInfo); - - TreeNode newTreeNode = new TreeNode(newContainerInfo.Name); - newTreeNode.Tag = newContainerInfo; - newTreeNode.ImageIndex = (int)TreeImageType.Container; - newTreeNode.SelectedImageIndex = (int)TreeImageType.Container; - newContainerInfo.Parent = newContainerInfo; - - Runtime.ContainerList.Add(newContainerInfo); - - if (parentNode == null) - { - oldTreeNode.Parent.Nodes.Insert(oldTreeNode.Index + 1, newTreeNode); - ConnectionTree.SelectedNode = newTreeNode; - } - else - { - parentNode.Nodes.Add(newTreeNode); - } - - foreach (TreeNode childTreeNode in oldTreeNode.Nodes) - { - CloneNode(childTreeNode, newTreeNode); - } - - newTreeNode.Expand(); - } - - private static void CloneConnectionNode(TreeNode oldTreeNode, TreeNode parentNode) - { - ConnectionInfo oldConnectionInfo = (ConnectionInfo)oldTreeNode.Tag; - - ConnectionInfo newConnectionInfo = oldConnectionInfo.Copy(); - ConnectionInfoInheritance newInheritance = oldConnectionInfo.Inheritance.Copy(); - newInheritance.Parent = newConnectionInfo; - newConnectionInfo.Inheritance = newInheritance; - - Runtime.ConnectionList.Add(newConnectionInfo); - - TreeNode newTreeNode = new TreeNode(newConnectionInfo.Name) - { - Tag = newConnectionInfo, - ImageIndex = (int) TreeImageType.ConnectionClosed, - SelectedImageIndex = (int) TreeImageType.ConnectionClosed - }; - - newConnectionInfo.TreeNode = newTreeNode; - - if (parentNode == null) - { - oldTreeNode.Parent.Nodes.Insert(oldTreeNode.Index + 1, newTreeNode); - ConnectionTree.SelectedNode = newTreeNode; - } - else - { - ContainerInfo parentContainerInfo = parentNode.Tag as ContainerInfo; - if (parentContainerInfo != null) - { - newConnectionInfo.Parent = parentContainerInfo; - } - parentNode.Nodes.Add(newTreeNode); - } - } - - public static void SetNodeImage(TreeNode treeNode, TreeImageType Img) - { - SetNodeImageIndex(treeNode, (int)Img); - } - - public static void RenameNode(ConnectionInfo connectionInfo, string newName) - { - if (newName == null || newName.Length <= 0) - return; - - connectionInfo.Name = newName; - if (Settings.Default.SetHostnameLikeDisplayName) - connectionInfo.Hostname = newName; - } - #endregion - - #region Private Methods - private delegate void SetNodeImageIndexDelegate(TreeNode treeNode, int imageIndex); - private static void SetNodeImageIndex(TreeNode treeNode, int imageIndex) - { - if (treeNode?.TreeView == null) - { - return; - } - if (treeNode.TreeView.InvokeRequired) - { - treeNode.TreeView.Invoke(new SetNodeImageIndexDelegate(SetNodeImageIndex), new object[] { treeNode, imageIndex }); - return; - } - - treeNode.ImageIndex = imageIndex; - treeNode.SelectedImageIndex = imageIndex; - } - #endregion - } -} \ No newline at end of file diff --git a/mRemoteV1/Tree/NodeSearcher.cs b/mRemoteV1/Tree/NodeSearcher.cs new file mode 100644 index 000000000..359585794 --- /dev/null +++ b/mRemoteV1/Tree/NodeSearcher.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Connection; + + +namespace mRemoteNG.Tree +{ + internal class NodeSearcher + { + private readonly ConnectionTreeModel _connectionTreeModel; + + public List Matches { get; private set; } + public ConnectionInfo CurrentMatch { get; private set; } + + + public NodeSearcher(ConnectionTreeModel connectionTreeModel) + { + _connectionTreeModel = connectionTreeModel; + } + + internal IEnumerable SearchByName(string searchText) + { + ResetMatches(); + if (searchText == "") return Matches; + var nodes = (List)_connectionTreeModel.GetRecursiveChildList(); + foreach (var node in nodes) + { + if (node.Name.ToLowerInvariant().Contains(searchText.ToLowerInvariant())) + Matches.Add(node); + } + if (Matches.Count > 0) + CurrentMatch = Matches.First(); + return Matches; + } + + internal ConnectionInfo NextMatch() + { + var currentMatchIndex = Matches.IndexOf(CurrentMatch); + if (currentMatchIndex < Matches.Count-1) + CurrentMatch = Matches[currentMatchIndex + 1]; + return CurrentMatch; + } + + internal ConnectionInfo PreviousMatch() + { + var currentMatchIndex = Matches.IndexOf(CurrentMatch); + if (currentMatchIndex > 0) + CurrentMatch = Matches[currentMatchIndex - 1]; + return CurrentMatch; + } + + private void ResetMatches() + { + Matches = new List(); + CurrentMatch = null; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/ObjectListViewExtensions.cs b/mRemoteV1/Tree/ObjectListViewExtensions.cs new file mode 100644 index 000000000..2e7c1b554 --- /dev/null +++ b/mRemoteV1/Tree/ObjectListViewExtensions.cs @@ -0,0 +1,24 @@ +using System.Windows.Forms; +using BrightIdeasSoftware; + + +namespace mRemoteNG.Tree +{ + public static class ObjectListViewExtensions + { + public static void Invoke(this Control control, MethodInvoker action) + { + control.Invoke(action); + } + + public static void InvokeExpand(this TreeListView control, object model) + { + control.Invoke(() => control.Expand(model)); + } + + public static void InvokeRebuildAll(this TreeListView control, bool preserveState) + { + control.Invoke(() => control.RebuildAll(preserveState)); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Tree/Root/RootNodeInfo.cs b/mRemoteV1/Tree/Root/RootNodeInfo.cs index 31119418a..93c27226e 100644 --- a/mRemoteV1/Tree/Root/RootNodeInfo.cs +++ b/mRemoteV1/Tree/Root/RootNodeInfo.cs @@ -7,41 +7,29 @@ namespace mRemoteNG.Tree.Root { [DefaultProperty("Name")] public class RootNodeInfo : ContainerInfo - { - private string _name; + { + private string _name; - - public RootNodeInfo(RootNodeType rootType) + public RootNodeInfo(RootNodeType rootType) { - _name = Language.strConnections; + _name = Language.strConnections; Type = rootType; } - + #region Public Properties - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay"), - Browsable(true), - LocalizedAttributes.LocalizedDefaultValue("strConnections"), - LocalizedAttributes.LocalizedDisplayName("strPropertyNameName"), - LocalizedAttributes.LocalizedDescription("strPropertyDescriptionName")] - public override string Name - { - get { return _name; } - set - { - if (_name == value) - { - return ; - } - _name = value; - if (TreeNode != null) - { - TreeNode.Name = value; - TreeNode.Text = value; - } - } - } - [LocalizedAttributes.LocalizedCategory("strCategoryDisplay"), + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay"), + Browsable(true), + LocalizedAttributes.LocalizedDefaultValue("strConnections"), + LocalizedAttributes.LocalizedDisplayName("strPropertyNameName"), + LocalizedAttributes.LocalizedDescription("strPropertyDescriptionName")] + public override string Name + { + get { return _name; } + set { _name = value; } + } + + [LocalizedAttributes.LocalizedCategory("strCategoryDisplay"), Browsable(true), LocalizedAttributes.LocalizedDisplayName("strPasswordProtect"), TypeConverter(typeof(Tools.MiscTools.YesNoTypeConverter))] @@ -52,6 +40,11 @@ namespace mRemoteNG.Tree.Root [Browsable(false)] public RootNodeType Type {get; set;} + + public override TreeNodeType GetTreeNodeType() + { + return TreeNodeType.Root; + } #endregion - } + } } \ No newline at end of file diff --git a/mRemoteV1/Tree/Root/PuttySessionsNodeInfo.cs b/mRemoteV1/Tree/Root/RootPuttySessionsNodeInfo.cs similarity index 57% rename from mRemoteV1/Tree/Root/PuttySessionsNodeInfo.cs rename to mRemoteV1/Tree/Root/RootPuttySessionsNodeInfo.cs index 18725164e..f9dc31216 100644 --- a/mRemoteV1/Tree/Root/PuttySessionsNodeInfo.cs +++ b/mRemoteV1/Tree/Root/RootPuttySessionsNodeInfo.cs @@ -1,19 +1,23 @@ using mRemoteNG.Tools; using mRemoteNG.Tree.Root; +using mRemoteNG.Tree; namespace mRemoteNG.Root.PuttySessions { - public class PuttySessionsNodeInfo : RootNodeInfo + public class RootPuttySessionsNodeInfo : RootNodeInfo { private string _name; private string _panel; - public PuttySessionsNodeInfo() : base(RootNodeType.PuttySessions) - { - _name = Language.strPuttySavedSessionsRootName; - _panel = Language.strGeneral; + public RootPuttySessionsNodeInfo() : base(RootNodeType.PuttySessions) + { + _name = Language.strPuttySavedSessionsRootName; + _panel = + string.IsNullOrEmpty(Settings.Default.PuttySavedSessionsPanel) + ? Language.strGeneral + : Settings.Default.PuttySavedSessionsPanel; } #region Public Properties @@ -23,16 +27,8 @@ namespace mRemoteNG.Root.PuttySessions get { return _name; } set { - if (_name == value) - { - return ; - } _name = value; - if (TreeNode != null) - { - TreeNode.Text = value; - } - Settings.Default.PuttySavedSessionsName = value; + //Settings.Default.PuttySavedSessionsName = value; } } @@ -44,14 +40,15 @@ namespace mRemoteNG.Root.PuttySessions get { return _panel; } set { - if (_panel == value) - { - return ; - } _panel = value; Settings.Default.PuttySavedSessionsPanel = value; } } + + public override TreeNodeType GetTreeNodeType() + { + return TreeNodeType.PuttyRoot; + } #endregion } } \ No newline at end of file diff --git a/mRemoteV1/Tree/TreeImageType.cs b/mRemoteV1/Tree/TreeImageType.cs deleted file mode 100644 index 19beba369..000000000 --- a/mRemoteV1/Tree/TreeImageType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace mRemoteNG.Tree -{ - public enum TreeImageType - { - Root = 0, - Container = 1, - ConnectionOpen = 2, - ConnectionClosed = 3, - PuttySessions = 4 - } -} \ No newline at end of file diff --git a/mRemoteV1/Tree/TreeNodeMover.cs b/mRemoteV1/Tree/TreeNodeMover.cs deleted file mode 100644 index eda89dedc..000000000 --- a/mRemoteV1/Tree/TreeNodeMover.cs +++ /dev/null @@ -1,89 +0,0 @@ -using mRemoteNG.App; -using mRemoteNG.Connection; -using mRemoteNG.Container; -using System.Windows.Forms; - -namespace mRemoteNG.Tree -{ - public class TreeNodeMover - { - TreeNode _nodeBeingMoved; - - public TreeNodeMover (TreeNode NodeBeingMoved) - { - _nodeBeingMoved = NodeBeingMoved; - } - - public void MoveNode(TreeNode TargetNode) - { - if (WeAreAllowedToMoveThisNode(TargetNode)) - { - RemoveNodeFromCurrentLocation(); - AddNodeToNewLocation(TargetNode); - UpdateParentReferences(); - SelectTheNewNode(); - Runtime.SaveConnectionsBG(); - } - } - - private bool WeAreAllowedToMoveThisNode(TreeNode targetNode) - { - bool weShouldMoveThisNode = true; - - if (_nodeBeingMoved == targetNode) - weShouldMoveThisNode = false; - if (ConnectionTreeNode.GetNodeType(_nodeBeingMoved) == TreeNodeType.Root) - weShouldMoveThisNode = false; - if (_nodeBeingMoved == targetNode.Parent) - weShouldMoveThisNode = false; - - return weShouldMoveThisNode; - } - - private void RemoveNodeFromCurrentLocation() - { - _nodeBeingMoved.Remove(); - } - - private void AddNodeToNewLocation(TreeNode targetNode) - { - //If there is no targetNode add dropNode to the bottom of - //the TreeView root nodes, otherwise add it to the end of - //the dropNode child nodes - if (ConnectionTreeNode.GetNodeType(targetNode) == TreeNodeType.Root | ConnectionTreeNode.GetNodeType(targetNode) == TreeNodeType.Container) - targetNode.Nodes.Insert(0, _nodeBeingMoved); - else - targetNode.Parent.Nodes.Insert(targetNode.Index + 1, _nodeBeingMoved); - } - - private void UpdateParentReferences() - { - UpdateParentReferenceWhenParentIsAContainer(); - UpdateParentReferenceWhenParentIsRoot(); - } - - private void UpdateParentReferenceWhenParentIsAContainer() - { - if (ConnectionTreeNode.GetNodeType(_nodeBeingMoved.Parent) == TreeNodeType.Container) - { - ((IParent)_nodeBeingMoved.Tag).Parent = (ContainerInfo)_nodeBeingMoved.Parent.Tag; - ((IInheritable)_nodeBeingMoved.Tag).Inheritance.EnableInheritance(); - } - } - - private void UpdateParentReferenceWhenParentIsRoot() - { - if (ConnectionTreeNode.GetNodeType(_nodeBeingMoved.Parent) == TreeNodeType.Root) - { - ((IParent)_nodeBeingMoved.Tag).Parent = null; - ((IInheritable)_nodeBeingMoved.Tag).Inheritance.DisableInheritance(); - } - } - - private void SelectTheNewNode() - { - _nodeBeingMoved.EnsureVisible(); - _nodeBeingMoved.TreeView.SelectedNode = _nodeBeingMoved; - } - } -} \ No newline at end of file diff --git a/mRemoteV1/UI/Controls/ConnectionContextMenu.cs b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs new file mode 100644 index 000000000..2cb5e2313 --- /dev/null +++ b/mRemoteV1/UI/Controls/ConnectionContextMenu.cs @@ -0,0 +1,714 @@ +using System; +using System.Linq; +using System.Windows.Forms; +using mRemoteNG.App; +using mRemoteNG.Connection; +using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; +using mRemoteNG.Root.PuttySessions; +using mRemoteNG.Tools; +using mRemoteNG.Tree.Root; + + +namespace mRemoteNG.UI.Controls +{ + internal class ConnectionContextMenu : ContextMenuStrip + { + private ToolStripMenuItem _cMenTreeAddConnection; + private ToolStripMenuItem _cMenTreeAddFolder; + private ToolStripSeparator _cMenTreeSep1; + private ToolStripMenuItem _cMenTreeConnect; + private ToolStripMenuItem _cMenTreeConnectWithOptions; + private ToolStripMenuItem _cMenTreeConnectWithOptionsConnectToConsoleSession; + private ToolStripMenuItem _cMenTreeConnectWithOptionsNoCredentials; + private ToolStripMenuItem _cMenTreeConnectWithOptionsConnectInFullscreen; + private ToolStripMenuItem _cMenTreeDisconnect; + private ToolStripSeparator _cMenTreeSep2; + private ToolStripMenuItem _cMenTreeToolsTransferFile; + private ToolStripMenuItem _cMenTreeToolsSort; + private ToolStripMenuItem _cMenTreeToolsSortAscending; + private ToolStripMenuItem _cMenTreeToolsSortDescending; + private ToolStripSeparator _cMenTreeSep3; + private ToolStripMenuItem _cMenTreeRename; + private ToolStripMenuItem _cMenTreeDelete; + private ToolStripSeparator _cMenTreeSep4; + private ToolStripMenuItem _cMenTreeMoveUp; + private ToolStripMenuItem _cMenTreeMoveDown; + private PictureBox _pictureBox1; + private ToolStripMenuItem _cMenTreeToolsExternalApps; + private ToolStripMenuItem _cMenTreeDuplicate; + private ToolStripMenuItem _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting; + private ToolStripMenuItem _cMenTreeConnectWithOptionsDontConnectToConsoleSession; + private ToolStripMenuItem _cMenTreeImport; + private ToolStripMenuItem _cMenTreeExportFile; + private ToolStripSeparator _toolStripSeparator1; + private ToolStripMenuItem _cMenTreeImportFile; + private ToolStripMenuItem _cMenTreeImportActiveDirectory; + private ToolStripMenuItem _cMenTreeImportPortScan; + + + public ConnectionContextMenu() + { + InitializeComponent(); + ApplyLanguage(); + EnableShortcutKeys(); + Opening += (sender, args) => AddExternalApps(); + } + + private void InitializeComponent() + { + _cMenTreeConnect = new ToolStripMenuItem(); + _cMenTreeConnectWithOptions = new ToolStripMenuItem(); + _cMenTreeConnectWithOptionsConnectToConsoleSession = new ToolStripMenuItem(); + _cMenTreeConnectWithOptionsDontConnectToConsoleSession = new ToolStripMenuItem(); + _cMenTreeConnectWithOptionsConnectInFullscreen = new ToolStripMenuItem(); + _cMenTreeConnectWithOptionsNoCredentials = new ToolStripMenuItem(); + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting = new ToolStripMenuItem(); + _cMenTreeDisconnect = new ToolStripMenuItem(); + _cMenTreeSep1 = new ToolStripSeparator(); + _cMenTreeToolsExternalApps = new ToolStripMenuItem(); + _cMenTreeToolsTransferFile = new ToolStripMenuItem(); + _cMenTreeSep2 = new ToolStripSeparator(); + _cMenTreeDuplicate = new ToolStripMenuItem(); + _cMenTreeRename = new ToolStripMenuItem(); + _cMenTreeDelete = new ToolStripMenuItem(); + _cMenTreeSep3 = new ToolStripSeparator(); + _cMenTreeImport = new ToolStripMenuItem(); + _cMenTreeImportFile = new ToolStripMenuItem(); + _cMenTreeImportActiveDirectory = new ToolStripMenuItem(); + _cMenTreeImportPortScan = new ToolStripMenuItem(); + _cMenTreeExportFile = new ToolStripMenuItem(); + _cMenTreeSep4 = new ToolStripSeparator(); + _cMenTreeAddConnection = new ToolStripMenuItem(); + _cMenTreeAddFolder = new ToolStripMenuItem(); + _toolStripSeparator1 = new ToolStripSeparator(); + _cMenTreeToolsSort = new ToolStripMenuItem(); + _cMenTreeToolsSortAscending = new ToolStripMenuItem(); + _cMenTreeToolsSortDescending = new ToolStripMenuItem(); + _cMenTreeMoveUp = new ToolStripMenuItem(); + _cMenTreeMoveDown = new ToolStripMenuItem(); + + + // + // cMenTree + // + Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + Items.AddRange(new ToolStripItem[] { + _cMenTreeConnect, + _cMenTreeConnectWithOptions, + _cMenTreeDisconnect, + _cMenTreeSep1, + _cMenTreeToolsExternalApps, + _cMenTreeToolsTransferFile, + _cMenTreeSep2, + _cMenTreeDuplicate, + _cMenTreeRename, + _cMenTreeDelete, + _cMenTreeSep3, + _cMenTreeImport, + _cMenTreeExportFile, + _cMenTreeSep4, + _cMenTreeAddConnection, + _cMenTreeAddFolder, + _toolStripSeparator1, + _cMenTreeToolsSort, + _cMenTreeMoveUp, + _cMenTreeMoveDown + }); + Name = "cMenTree"; + RenderMode = ToolStripRenderMode.Professional; + Size = new System.Drawing.Size(200, 364); + // + // cMenTreeConnect + // + _cMenTreeConnect.Image = Resources.Play; + _cMenTreeConnect.Name = "_cMenTreeConnect"; + _cMenTreeConnect.Size = new System.Drawing.Size(199, 22); + _cMenTreeConnect.Text = "Connect"; + _cMenTreeConnect.Click += (sender, args) => OnConnectClicked(args); + // + // cMenTreeConnectWithOptions + // + _cMenTreeConnectWithOptions.DropDownItems.AddRange(new ToolStripItem[] { + _cMenTreeConnectWithOptionsConnectToConsoleSession, + _cMenTreeConnectWithOptionsDontConnectToConsoleSession, + _cMenTreeConnectWithOptionsConnectInFullscreen, + _cMenTreeConnectWithOptionsNoCredentials, + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting + }); + _cMenTreeConnectWithOptions.Name = "_cMenTreeConnectWithOptions"; + _cMenTreeConnectWithOptions.Size = new System.Drawing.Size(199, 22); + _cMenTreeConnectWithOptions.Text = "Connect (with options)"; + // + // cMenTreeConnectWithOptionsConnectToConsoleSession + // + _cMenTreeConnectWithOptionsConnectToConsoleSession.Image = Resources.monitor_go; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Name = "_cMenTreeConnectWithOptionsConnectToConsoleSession"; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Size = new System.Drawing.Size(245, 22); + _cMenTreeConnectWithOptionsConnectToConsoleSession.Text = "Connect to console session"; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Click += (sender, args) => OnConnectToConsoleSessionClicked(args); + // + // cMenTreeConnectWithOptionsDontConnectToConsoleSession + // + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Image = Resources.monitor_delete; + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Name = "_cMenTreeConnectWithOptionsDontConnectToConsoleSession"; + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Size = new System.Drawing.Size(245, 22); + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Text = "Don\'t connect to console session"; + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Visible = false; + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Click += (sender, args) => OnDontConnectToConsoleSessionClicked(args); + // + // cMenTreeConnectWithOptionsConnectInFullscreen + // + _cMenTreeConnectWithOptionsConnectInFullscreen.Image = Resources.arrow_out; + _cMenTreeConnectWithOptionsConnectInFullscreen.Name = "_cMenTreeConnectWithOptionsConnectInFullscreen"; + _cMenTreeConnectWithOptionsConnectInFullscreen.Size = new System.Drawing.Size(245, 22); + _cMenTreeConnectWithOptionsConnectInFullscreen.Text = "Connect in fullscreen"; + _cMenTreeConnectWithOptionsConnectInFullscreen.Click += (sender, args) => OnConnectInFullscreenClicked(args); + // + // cMenTreeConnectWithOptionsNoCredentials + // + _cMenTreeConnectWithOptionsNoCredentials.Image = Resources.key_delete; + _cMenTreeConnectWithOptionsNoCredentials.Name = "_cMenTreeConnectWithOptionsNoCredentials"; + _cMenTreeConnectWithOptionsNoCredentials.Size = new System.Drawing.Size(245, 22); + _cMenTreeConnectWithOptionsNoCredentials.Text = "Connect without credentials"; + _cMenTreeConnectWithOptionsNoCredentials.Click += (sender, args) => OnConnectWithNoCredentialsClick(args); + // + // cMenTreeConnectWithOptionsChoosePanelBeforeConnecting + // + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Image = Resources.Panels; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Name = "_cMenTreeConnectWithOptionsChoosePanelBeforeConnecting"; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Size = new System.Drawing.Size(245, 22); + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Text = "Choose panel before connecting"; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Click += (sender, args) => OnChoosePanelBeforeConnectingClicked(args); + // + // cMenTreeDisconnect + // + _cMenTreeDisconnect.Image = Resources.Pause; + _cMenTreeDisconnect.Name = "_cMenTreeDisconnect"; + _cMenTreeDisconnect.Size = new System.Drawing.Size(199, 22); + _cMenTreeDisconnect.Text = "Disconnect"; + _cMenTreeDisconnect.Click += (sender, args) => OnDisconnectClicked(args); + // + // cMenTreeSep1 + // + _cMenTreeSep1.Name = "_cMenTreeSep1"; + _cMenTreeSep1.Size = new System.Drawing.Size(196, 6); + // + // cMenTreeToolsExternalApps + // + _cMenTreeToolsExternalApps.Image = Resources.ExtApp; + _cMenTreeToolsExternalApps.Name = "_cMenTreeToolsExternalApps"; + _cMenTreeToolsExternalApps.Size = new System.Drawing.Size(199, 22); + _cMenTreeToolsExternalApps.Text = "External Applications"; + // + // cMenTreeToolsTransferFile + // + _cMenTreeToolsTransferFile.Image = Resources.SSHTransfer; + _cMenTreeToolsTransferFile.Name = "_cMenTreeToolsTransferFile"; + _cMenTreeToolsTransferFile.Size = new System.Drawing.Size(199, 22); + _cMenTreeToolsTransferFile.Text = "Transfer File (SSH)"; + _cMenTreeToolsTransferFile.Click += (sender, args) => OnTransferFileClicked(args); + // + // cMenTreeSep2 + // + _cMenTreeSep2.Name = "_cMenTreeSep2"; + _cMenTreeSep2.Size = new System.Drawing.Size(196, 6); + // + // cMenTreeDuplicate + // + _cMenTreeDuplicate.Image = Resources.page_copy; + _cMenTreeDuplicate.Name = "_cMenTreeDuplicate"; + _cMenTreeDuplicate.Size = new System.Drawing.Size(199, 22); + _cMenTreeDuplicate.Text = "Duplicate"; + _cMenTreeDuplicate.Click += (sender, args) => OnDuplicateClicked(args); + // + // cMenTreeRename + // + _cMenTreeRename.Image = Resources.Rename; + _cMenTreeRename.Name = "_cMenTreeRename"; + _cMenTreeRename.Size = new System.Drawing.Size(199, 22); + _cMenTreeRename.Text = "Rename"; + _cMenTreeRename.Click += (sender, args) => OnRenameClicked(args); + // + // cMenTreeDelete + // + _cMenTreeDelete.Image = Resources.Delete; + _cMenTreeDelete.Name = "_cMenTreeDelete"; + _cMenTreeDelete.Size = new System.Drawing.Size(199, 22); + _cMenTreeDelete.Text = "Delete"; + _cMenTreeDelete.Click += (sender, args) => OnDeleteClicked(args); + // + // cMenTreeSep3 + // + _cMenTreeSep3.Name = "_cMenTreeSep3"; + _cMenTreeSep3.Size = new System.Drawing.Size(196, 6); + // + // cMenTreeImport + // + _cMenTreeImport.DropDownItems.AddRange(new ToolStripItem[] { + _cMenTreeImportFile, + _cMenTreeImportActiveDirectory, + _cMenTreeImportPortScan + }); + _cMenTreeImport.Name = "_cMenTreeImport"; + _cMenTreeImport.Size = new System.Drawing.Size(199, 22); + _cMenTreeImport.Text = "&Import"; + // + // cMenTreeImportFile + // + _cMenTreeImportFile.Name = "_cMenTreeImportFile"; + _cMenTreeImportFile.Size = new System.Drawing.Size(226, 22); + _cMenTreeImportFile.Text = "Import from &File..."; + _cMenTreeImportFile.Click += (sender, args) => OnImportFileClicked(args); + // + // cMenTreeImportActiveDirectory + // + _cMenTreeImportActiveDirectory.Name = "_cMenTreeImportActiveDirectory"; + _cMenTreeImportActiveDirectory.Size = new System.Drawing.Size(226, 22); + _cMenTreeImportActiveDirectory.Text = "Import from &Active Directory..."; + _cMenTreeImportActiveDirectory.Click += (sender, args) => OnImportActiveDirectoryClicked(args); + // + // cMenTreeImportPortScan + // + _cMenTreeImportPortScan.Name = "_cMenTreeImportPortScan"; + _cMenTreeImportPortScan.Size = new System.Drawing.Size(226, 22); + _cMenTreeImportPortScan.Text = "Import from &Port Scan..."; + _cMenTreeImportPortScan.Click += (sender, args) => OnImportPortScanClicked(args); + // + // cMenTreeExportFile + // + _cMenTreeExportFile.Name = "_cMenTreeExportFile"; + _cMenTreeExportFile.Size = new System.Drawing.Size(199, 22); + _cMenTreeExportFile.Text = "&Export to File..."; + _cMenTreeExportFile.Click += (sender, args) => OnExportFileClicked(args); + // + // cMenTreeSep4 + // + _cMenTreeSep4.Name = "_cMenTreeSep4"; + _cMenTreeSep4.Size = new System.Drawing.Size(196, 6); + // + // cMenTreeAddConnection + // + _cMenTreeAddConnection.Image = Resources.Connection_Add; + _cMenTreeAddConnection.Name = "_cMenTreeAddConnection"; + _cMenTreeAddConnection.Size = new System.Drawing.Size(199, 22); + _cMenTreeAddConnection.Text = "New Connection"; + _cMenTreeAddConnection.Click += (sender, args) => OnAddConnectionClicked(args); + // + // cMenTreeAddFolder + // + _cMenTreeAddFolder.Image = Resources.Folder_Add; + _cMenTreeAddFolder.Name = "_cMenTreeAddFolder"; + _cMenTreeAddFolder.Size = new System.Drawing.Size(199, 22); + _cMenTreeAddFolder.Text = "New Folder"; + _cMenTreeAddFolder.Click += (sender, args) => OnAddFolderClicked(args); + // + // ToolStripSeparator1 + // + _toolStripSeparator1.Name = "_toolStripSeparator1"; + _toolStripSeparator1.Size = new System.Drawing.Size(196, 6); + // + // cMenTreeToolsSort + // + _cMenTreeToolsSort.DropDownItems.AddRange(new ToolStripItem[] { + _cMenTreeToolsSortAscending, + _cMenTreeToolsSortDescending + }); + _cMenTreeToolsSort.Name = "_cMenTreeToolsSort"; + _cMenTreeToolsSort.Size = new System.Drawing.Size(199, 22); + _cMenTreeToolsSort.Text = "Sort"; + // + // cMenTreeToolsSortAscending + // + _cMenTreeToolsSortAscending.Image = Resources.Sort_AZ; + _cMenTreeToolsSortAscending.Name = "_cMenTreeToolsSortAscending"; + _cMenTreeToolsSortAscending.Size = new System.Drawing.Size(161, 22); + _cMenTreeToolsSortAscending.Text = "Ascending (A-Z)"; + _cMenTreeToolsSortAscending.Click += (sender, args) => OnSortAscendingClicked(args); + // + // cMenTreeToolsSortDescending + // + _cMenTreeToolsSortDescending.Image = Resources.Sort_ZA; + _cMenTreeToolsSortDescending.Name = "_cMenTreeToolsSortDescending"; + _cMenTreeToolsSortDescending.Size = new System.Drawing.Size(161, 22); + _cMenTreeToolsSortDescending.Text = "Descending (Z-A)"; + _cMenTreeToolsSortDescending.Click += (sender, args) => OnSortDescendingClicked(args); + // + // cMenTreeMoveUp + // + _cMenTreeMoveUp.Image = Resources.Arrow_Up; + _cMenTreeMoveUp.Name = "_cMenTreeMoveUp"; + _cMenTreeMoveUp.Size = new System.Drawing.Size(199, 22); + _cMenTreeMoveUp.Text = "Move up"; + _cMenTreeMoveUp.Click += (sender, args) => OnMoveUpClicked(args); + // + // cMenTreeMoveDown + // + _cMenTreeMoveDown.Image = Resources.Arrow_Down; + _cMenTreeMoveDown.Name = "_cMenTreeMoveDown"; + _cMenTreeMoveDown.Size = new System.Drawing.Size(199, 22); + _cMenTreeMoveDown.Text = "Move down"; + _cMenTreeMoveDown.Click += (sender, args) => OnMoveDownClicked(args); + } + + private void ApplyLanguage() + { + _cMenTreeConnect.Text = Language.strConnect; + _cMenTreeConnectWithOptions.Text = Language.strConnectWithOptions; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Text = Language.strConnectToConsoleSession; + _cMenTreeConnectWithOptionsDontConnectToConsoleSession.Text = Language.strDontConnectToConsoleSessionMenuItem; + _cMenTreeConnectWithOptionsConnectInFullscreen.Text = Language.strConnectInFullscreen; + _cMenTreeConnectWithOptionsNoCredentials.Text = Language.strConnectNoCredentials; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Text = Language.strChoosePanelBeforeConnecting; + _cMenTreeDisconnect.Text = Language.strMenuDisconnect; + + _cMenTreeToolsExternalApps.Text = Language.strMenuExternalTools; + _cMenTreeToolsTransferFile.Text = Language.strMenuTransferFile; + + _cMenTreeDuplicate.Text = Language.strDuplicate; + _cMenTreeRename.Text = Language.strRename; + _cMenTreeDelete.Text = Language.strMenuDelete; + + _cMenTreeImport.Text = Language.strImportMenuItem; + _cMenTreeImportFile.Text = Language.strImportFromFileMenuItem; + _cMenTreeImportActiveDirectory.Text = Language.strImportAD; + _cMenTreeImportPortScan.Text = Language.strImportPortScan; + _cMenTreeExportFile.Text = Language.strExportToFileMenuItem; + + _cMenTreeAddConnection.Text = Language.strAddConnection; + _cMenTreeAddFolder.Text = Language.strAddFolder; + + _cMenTreeToolsSort.Text = Language.strSort; + _cMenTreeToolsSortAscending.Text = Language.strSortAsc; + _cMenTreeToolsSortDescending.Text = Language.strSortDesc; + _cMenTreeMoveUp.Text = Language.strMoveUp; + _cMenTreeMoveDown.Text = Language.strMoveDown; + } + + internal void ShowHideTreeContextMenuItems(ConnectionInfo connectionInfo) + { + if (connectionInfo == null) + return; + + try + { + Enabled = true; + EnableMenuItemsRecursive(Items); + if (connectionInfo is RootPuttySessionsNodeInfo) + { + _cMenTreeAddConnection.Enabled = false; + _cMenTreeAddFolder.Enabled = false; + _cMenTreeConnect.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeToolsSort.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeRename.Enabled = true; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + else if (connectionInfo is RootNodeInfo) + { + _cMenTreeConnect.Enabled = false; + _cMenTreeConnectWithOptions.Enabled = false; + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + else if (connectionInfo is ContainerInfo) + { + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeDisconnect.Enabled = false; + + var openConnections = ((ContainerInfo)connectionInfo).Children.Sum(child => child.OpenConnections.Count); + if (openConnections > 0) + _cMenTreeDisconnect.Enabled = true; + + _cMenTreeToolsTransferFile.Enabled = false; + _cMenTreeToolsExternalApps.Enabled = false; + } + else if (connectionInfo is PuttySessionInfo) + { + _cMenTreeAddConnection.Enabled = false; + _cMenTreeAddFolder.Enabled = false; + + if (connectionInfo.OpenConnections.Count == 0) + _cMenTreeDisconnect.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) + _cMenTreeToolsTransferFile.Enabled = false; + + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + _cMenTreeToolsSort.Enabled = false; + _cMenTreeDuplicate.Enabled = false; + _cMenTreeRename.Enabled = false; + _cMenTreeDelete.Enabled = false; + _cMenTreeMoveUp.Enabled = false; + _cMenTreeMoveDown.Enabled = false; + } + else + { + if (connectionInfo.OpenConnections.Count == 0) + _cMenTreeDisconnect.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.SSH1 | connectionInfo.Protocol == ProtocolType.SSH2)) + _cMenTreeToolsTransferFile.Enabled = false; + + if (!(connectionInfo.Protocol == ProtocolType.RDP | connectionInfo.Protocol == ProtocolType.ICA)) + { + _cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; + _cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; + } + + if (connectionInfo.Protocol == ProtocolType.IntApp) + _cMenTreeConnectWithOptionsNoCredentials.Enabled = false; + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("ShowHideTreeContextMenuItems (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + internal void DisableShortcutKeys() + { + _cMenTreeConnect.ShortcutKeys = Keys.None; + _cMenTreeDuplicate.ShortcutKeys = Keys.None; + _cMenTreeRename.ShortcutKeys = Keys.None; + _cMenTreeDelete.ShortcutKeys = Keys.None; + _cMenTreeMoveUp.ShortcutKeys = Keys.None; + _cMenTreeMoveDown.ShortcutKeys = Keys.None; + } + + internal void EnableShortcutKeys() + { + _cMenTreeConnect.ShortcutKeys = ((Keys.Control | Keys.Shift) | Keys.C); + _cMenTreeDuplicate.ShortcutKeys = Keys.Control | Keys.D; + _cMenTreeRename.ShortcutKeys = Keys.F2; + _cMenTreeDelete.ShortcutKeys = Keys.Delete; + _cMenTreeMoveUp.ShortcutKeys = Keys.Control | Keys.Up; + _cMenTreeMoveDown.ShortcutKeys = Keys.Control | Keys.Down; + } + + private static void EnableMenuItemsRecursive(ToolStripItemCollection items, bool enable = true) + { + foreach (ToolStripItem item in items) + { + var menuItem = item as ToolStripMenuItem; + if (menuItem == null) + { + continue; + } + menuItem.Enabled = enable; + if (menuItem.HasDropDownItems) + { + EnableMenuItemsRecursive(menuItem.DropDownItems, enable); + } + } + } + + private void AddExternalApps() + { + try + { + ResetExternalAppMenu(); + + foreach (ExternalTool extA in Runtime.ExternalTools) + { + var menuItem = new ToolStripMenuItem + { + Text = extA.DisplayName, + Tag = extA, + Image = extA.Image + }; + + menuItem.Click += OnExternalToolClicked; + _cMenTreeToolsExternalApps.DropDownItems.Add(menuItem); + } + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeTools_DropDownOpening failed (UI.Window.ConnectionTreeWindow)", ex); + } + } + + private void ResetExternalAppMenu() + { + if (_cMenTreeToolsExternalApps.DropDownItems.Count <= 0) return; + for (var i = _cMenTreeToolsExternalApps.DropDownItems.Count - 1; i >= 0; i--) + _cMenTreeToolsExternalApps.DropDownItems[i].Dispose(); + + _cMenTreeToolsExternalApps.DropDownItems.Clear(); + } + + #region Events + public event EventHandler ConnectClicked; + protected virtual void OnConnectClicked(EventArgs e) + { + var handler = ConnectClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ConnectToConsoleSessionClicked; + protected virtual void OnConnectToConsoleSessionClicked(EventArgs e) + { + var handler = ConnectToConsoleSessionClicked; + handler?.Invoke(this, e); + } + + public event EventHandler DontConnectToConsoleSessionClicked; + protected virtual void OnDontConnectToConsoleSessionClicked(EventArgs e) + { + var handler = DontConnectToConsoleSessionClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ConnectInFullscreenClicked; + protected virtual void OnConnectInFullscreenClicked(EventArgs e) + { + var handler = ConnectInFullscreenClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ConnectWithNoCredentialsClick; + protected virtual void OnConnectWithNoCredentialsClick(EventArgs e) + { + var handler = ConnectWithNoCredentialsClick; + handler?.Invoke(this, e); + } + + public event EventHandler ChoosePanelBeforeConnectingClicked; + protected virtual void OnChoosePanelBeforeConnectingClicked(EventArgs e) + { + var handler = ChoosePanelBeforeConnectingClicked; + handler?.Invoke(this, e); + } + + + public event EventHandler DisconnectClicked; + protected virtual void OnDisconnectClicked(EventArgs e) + { + var handler = DisconnectClicked; + handler?.Invoke(this, e); + } + + public event EventHandler TransferFileClicked; + protected virtual void OnTransferFileClicked(EventArgs e) + { + var handler = TransferFileClicked; + handler?.Invoke(this, e); + } + + public event EventHandler DuplicateClicked; + protected virtual void OnDuplicateClicked(EventArgs e) + { + var handler = DuplicateClicked; + handler?.Invoke(this, e); + } + + public event EventHandler RenameClicked; + protected virtual void OnRenameClicked(EventArgs e) + { + var handler = RenameClicked; + handler?.Invoke(this, e); + } + + public event EventHandler DeleteClicked; + protected virtual void OnDeleteClicked(EventArgs e) + { + var handler = DeleteClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ImportFileClicked; + protected virtual void OnImportFileClicked(EventArgs e) + { + var handler = ImportFileClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ImportActiveDirectoryClicked; + protected virtual void OnImportActiveDirectoryClicked(EventArgs e) + { + var handler = ImportActiveDirectoryClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ImportPortScanClicked; + protected virtual void OnImportPortScanClicked(EventArgs e) + { + var handler = ImportPortScanClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ExportFileClicked; + protected virtual void OnExportFileClicked(EventArgs e) + { + var handler = ExportFileClicked; + handler?.Invoke(this, e); + } + + public event EventHandler AddConnectionClicked; + protected virtual void OnAddConnectionClicked(EventArgs e) + { + var handler = AddConnectionClicked; + handler?.Invoke(this, e); + } + + public event EventHandler AddFolderClicked; + protected virtual void OnAddFolderClicked(EventArgs e) + { + var handler = AddFolderClicked; + handler?.Invoke(this, e); + } + + public event EventHandler SortAscendingClicked; + protected virtual void OnSortAscendingClicked(EventArgs e) + { + var handler = SortAscendingClicked; + handler?.Invoke(this, e); + } + + public event EventHandler SortDescendingClicked; + protected virtual void OnSortDescendingClicked(EventArgs e) + { + var handler = SortDescendingClicked; + handler?.Invoke(this, e); + } + + public event EventHandler MoveUpClicked; + protected virtual void OnMoveUpClicked(EventArgs e) + { + var handler = MoveUpClicked; + handler?.Invoke(this, e); + } + + public event EventHandler MoveDownClicked; + protected virtual void OnMoveDownClicked(EventArgs e) + { + var handler = MoveDownClicked; + handler?.Invoke(this, e); + } + + public event EventHandler ExternalToolClicked; + protected virtual void OnExternalToolClicked(object sender, EventArgs e) + { + var handler = ExternalToolClicked; + handler?.Invoke(sender, e); + } + #endregion + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/ExportForm.cs b/mRemoteV1/UI/Forms/ExportForm.cs index 493b1f780..05f16b3b1 100644 --- a/mRemoteV1/UI/Forms/ExportForm.cs +++ b/mRemoteV1/UI/Forms/ExportForm.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; using mRemoteNG.App; +using mRemoteNG.Config.Connections; +using mRemoteNG.Connection; +using mRemoteNG.Container; namespace mRemoteNG.UI.Forms { @@ -21,7 +24,7 @@ namespace mRemoteNG.UI.Forms } } - public Config.Connections.ConnectionsSaver.Format SaveFormat + public ConnectionsSaver.Format SaveFormat { get { @@ -83,8 +86,8 @@ namespace mRemoteNG.UI.Forms } } - private TreeNode _selectedFolder; - public TreeNode SelectedFolder + private ContainerInfo _selectedFolder; + public ContainerInfo SelectedFolder { get { @@ -93,13 +96,13 @@ namespace mRemoteNG.UI.Forms set { _selectedFolder = value; - lblSelectedFolder.Text = value == null ? string.Empty : value.Text; + lblSelectedFolder.Text = value?.Name; rdoExportSelectedFolder.Enabled = value != null; } } - private TreeNode _selectedConnection; - public TreeNode SelectedConnection + private ConnectionInfo _selectedConnection; + public ConnectionInfo SelectedConnection { get { @@ -108,7 +111,7 @@ namespace mRemoteNG.UI.Forms set { _selectedConnection = value; - lblSelectedConnection.Text = value == null ? string.Empty : value.Text; + lblSelectedConnection.Text = value?.Name; rdoExportSelectedConnection.Enabled = value != null; } } diff --git a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs index cc4b4623c..6cb5e7807 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/AdvancedPage.cs @@ -80,7 +80,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages if (puttyPathChanged) { PuttyBase.PuttyPath = Settings.Default.UseCustomPuttyPath ? Settings.Default.CustomPuttyPath : GeneralAppInfo.PuttyPath; - Sessions.AddSessionsToTree(); + PuttySessionsManager.Instance.AddSessions(); } Settings.Default.MaxPuttyWaitTime = (int) numPuttyWaitTime.Value; diff --git a/mRemoteV1/UI/Forms/OptionsPages/SqlServerPage.cs b/mRemoteV1/UI/Forms/OptionsPages/SqlServerPage.cs index 82cce92aa..f1edc0ba0 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/SqlServerPage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/SqlServerPage.cs @@ -62,15 +62,18 @@ namespace mRemoteNG.UI.Forms.OptionsPages private static void ReinitializeSqlUpdater() { - if (Runtime.SQLConnProvider != null) + Runtime.RemoteConnectionsSyncronizer?.Dispose(); + frmMain.Default.AreWeUsingSqlServerForSavingConnections = Settings.Default.UseSQLServer; + + if (Settings.Default.UseSQLServer) { - Runtime.SQLConnProvider.Dispose(); - frmMain.Default.AreWeUsingSqlServerForSavingConnections = Settings.Default.UseSQLServer; - if (Settings.Default.UseSQLServer) - { - Runtime.SQLConnProvider = new SqlConnectionsProvider(); - Runtime.SQLConnProvider.Enable(); - } + Runtime.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker()); + Runtime.RemoteConnectionsSyncronizer.Enable(); + } + else + { + Runtime.RemoteConnectionsSyncronizer?.Dispose(); + Runtime.RemoteConnectionsSyncronizer = null; } } diff --git a/mRemoteV1/UI/Forms/frmMain.Designer.cs b/mRemoteV1/UI/Forms/frmMain.Designer.cs index 95c7733ef..035f3e85e 100644 --- a/mRemoteV1/UI/Forms/frmMain.Designer.cs +++ b/mRemoteV1/UI/Forms/frmMain.Designer.cs @@ -97,7 +97,7 @@ namespace mRemoteNG.UI.Forms this.cmbQuickConnect = new mRemoteNG.UI.Controls.QuickConnectComboBox(); this.tsContainer = new System.Windows.Forms.ToolStripContainer(); this.tsQuickConnect = new System.Windows.Forms.ToolStrip(); - this.btnQuickConnect = new ToolStripSplitButton(); + this.btnQuickConnect = new mRemoteNG.UI.Controls.ToolStripSplitButton(); this.mnuQuickConnectProtocol = new System.Windows.Forms.ContextMenuStrip(this.components); this.btnConnections = new System.Windows.Forms.ToolStripDropDownButton(); this.mnuConnections = new System.Windows.Forms.ContextMenuStrip(this.components); @@ -143,10 +143,10 @@ namespace mRemoteNG.UI.Forms this.mMenView, this.mMenTools, this.mMenInfo}); - this.msMain.Location = new System.Drawing.Point(3, 0); + this.msMain.Location = new System.Drawing.Point(5, 0); this.msMain.Name = "msMain"; this.msMain.Padding = new System.Windows.Forms.Padding(2, 2, 0, 2); - this.msMain.Size = new System.Drawing.Size(176, 24); + this.msMain.Size = new System.Drawing.Size(269, 24); this.msMain.Stretch = false; this.msMain.TabIndex = 16; this.msMain.Text = "Main Toolbar"; @@ -363,7 +363,7 @@ namespace mRemoteNG.UI.Forms // this.mMenViewAddConnectionPanel.Image = global::mRemoteNG.Resources.Panel_Add; this.mMenViewAddConnectionPanel.Name = "mMenViewAddConnectionPanel"; - this.mMenViewAddConnectionPanel.Size = new System.Drawing.Size(227, 22); + this.mMenViewAddConnectionPanel.Size = new System.Drawing.Size(228, 22); this.mMenViewAddConnectionPanel.Text = "Add Connection Panel"; this.mMenViewAddConnectionPanel.Click += new System.EventHandler(this.mMenViewAddConnectionPanel_Click); // @@ -371,13 +371,13 @@ namespace mRemoteNG.UI.Forms // this.mMenViewConnectionPanels.Image = global::mRemoteNG.Resources.Panels; this.mMenViewConnectionPanels.Name = "mMenViewConnectionPanels"; - this.mMenViewConnectionPanels.Size = new System.Drawing.Size(227, 22); + this.mMenViewConnectionPanels.Size = new System.Drawing.Size(228, 22); this.mMenViewConnectionPanels.Text = "Connection Panels"; // // mMenViewSep1 // this.mMenViewSep1.Name = "mMenViewSep1"; - this.mMenViewSep1.Size = new System.Drawing.Size(224, 6); + this.mMenViewSep1.Size = new System.Drawing.Size(225, 6); // // mMenViewConnections // @@ -385,7 +385,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewConnections.CheckState = System.Windows.Forms.CheckState.Checked; this.mMenViewConnections.Image = global::mRemoteNG.Resources.Root; this.mMenViewConnections.Name = "mMenViewConnections"; - this.mMenViewConnections.Size = new System.Drawing.Size(227, 22); + this.mMenViewConnections.Size = new System.Drawing.Size(228, 22); this.mMenViewConnections.Text = "Connections"; this.mMenViewConnections.Click += new System.EventHandler(this.mMenViewConnections_Click); // @@ -395,7 +395,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewConfig.CheckState = System.Windows.Forms.CheckState.Checked; this.mMenViewConfig.Image = global::mRemoteNG.Resources.cog; this.mMenViewConfig.Name = "mMenViewConfig"; - this.mMenViewConfig.Size = new System.Drawing.Size(227, 22); + this.mMenViewConfig.Size = new System.Drawing.Size(228, 22); this.mMenViewConfig.Text = "Config"; this.mMenViewConfig.Click += new System.EventHandler(this.mMenViewConfig_Click); // @@ -405,7 +405,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewErrorsAndInfos.CheckState = System.Windows.Forms.CheckState.Checked; this.mMenViewErrorsAndInfos.Image = global::mRemoteNG.Resources.ErrorsAndInfos; this.mMenViewErrorsAndInfos.Name = "mMenViewErrorsAndInfos"; - this.mMenViewErrorsAndInfos.Size = new System.Drawing.Size(227, 22); + this.mMenViewErrorsAndInfos.Size = new System.Drawing.Size(228, 22); this.mMenViewErrorsAndInfos.Text = "Errors and Infos"; this.mMenViewErrorsAndInfos.Click += new System.EventHandler(this.mMenViewErrorsAndInfos_Click); // @@ -413,14 +413,14 @@ namespace mRemoteNG.UI.Forms // this.mMenViewScreenshotManager.Image = ((System.Drawing.Image)(resources.GetObject("mMenViewScreenshotManager.Image"))); this.mMenViewScreenshotManager.Name = "mMenViewScreenshotManager"; - this.mMenViewScreenshotManager.Size = new System.Drawing.Size(227, 22); + this.mMenViewScreenshotManager.Size = new System.Drawing.Size(228, 22); this.mMenViewScreenshotManager.Text = "Screenshot Manager"; this.mMenViewScreenshotManager.Click += new System.EventHandler(this.mMenViewScreenshotManager_Click); // // ToolStripSeparator1 // this.ToolStripSeparator1.Name = "ToolStripSeparator1"; - this.ToolStripSeparator1.Size = new System.Drawing.Size(224, 6); + this.ToolStripSeparator1.Size = new System.Drawing.Size(225, 6); // // mMenViewJumpTo // @@ -429,7 +429,7 @@ namespace mRemoteNG.UI.Forms this.mMenViewJumpToErrorsInfos}); this.mMenViewJumpTo.Image = global::mRemoteNG.Resources.JumpTo; this.mMenViewJumpTo.Name = "mMenViewJumpTo"; - this.mMenViewJumpTo.Size = new System.Drawing.Size(227, 22); + this.mMenViewJumpTo.Size = new System.Drawing.Size(228, 22); this.mMenViewJumpTo.Text = "Jump To"; // // mMenViewJumpToConnectionsConfig @@ -456,20 +456,20 @@ namespace mRemoteNG.UI.Forms // this.mMenViewResetLayout.Image = global::mRemoteNG.Resources.application_side_tree; this.mMenViewResetLayout.Name = "mMenViewResetLayout"; - this.mMenViewResetLayout.Size = new System.Drawing.Size(227, 22); + this.mMenViewResetLayout.Size = new System.Drawing.Size(228, 22); this.mMenViewResetLayout.Text = "Reset Layout"; this.mMenViewResetLayout.Click += new System.EventHandler(this.mMenViewResetLayout_Click); // // mMenViewSep2 // this.mMenViewSep2.Name = "mMenViewSep2"; - this.mMenViewSep2.Size = new System.Drawing.Size(224, 6); + this.mMenViewSep2.Size = new System.Drawing.Size(225, 6); // // mMenViewQuickConnectToolbar // this.mMenViewQuickConnectToolbar.Image = global::mRemoteNG.Resources.Play_Quick; this.mMenViewQuickConnectToolbar.Name = "mMenViewQuickConnectToolbar"; - this.mMenViewQuickConnectToolbar.Size = new System.Drawing.Size(227, 22); + this.mMenViewQuickConnectToolbar.Size = new System.Drawing.Size(228, 22); this.mMenViewQuickConnectToolbar.Text = "Quick Connect Toolbar"; this.mMenViewQuickConnectToolbar.Click += new System.EventHandler(this.mMenViewQuickConnectToolbar_Click); // @@ -477,21 +477,21 @@ namespace mRemoteNG.UI.Forms // this.mMenViewExtAppsToolbar.Image = global::mRemoteNG.Resources.ExtApp; this.mMenViewExtAppsToolbar.Name = "mMenViewExtAppsToolbar"; - this.mMenViewExtAppsToolbar.Size = new System.Drawing.Size(227, 22); + this.mMenViewExtAppsToolbar.Size = new System.Drawing.Size(228, 22); this.mMenViewExtAppsToolbar.Text = "External Applications Toolbar"; this.mMenViewExtAppsToolbar.Click += new System.EventHandler(this.mMenViewExtAppsToolbar_Click); // // mMenViewSep3 // this.mMenViewSep3.Name = "mMenViewSep3"; - this.mMenViewSep3.Size = new System.Drawing.Size(224, 6); + this.mMenViewSep3.Size = new System.Drawing.Size(225, 6); // // mMenViewFullscreen // this.mMenViewFullscreen.Image = global::mRemoteNG.Resources.arrow_out; this.mMenViewFullscreen.Name = "mMenViewFullscreen"; this.mMenViewFullscreen.ShortcutKeys = System.Windows.Forms.Keys.F11; - this.mMenViewFullscreen.Size = new System.Drawing.Size(227, 22); + this.mMenViewFullscreen.Size = new System.Drawing.Size(228, 22); this.mMenViewFullscreen.Text = "Full Screen"; this.mMenViewFullscreen.Click += new System.EventHandler(this.mMenViewFullscreen_Click); // @@ -506,7 +506,7 @@ namespace mRemoteNG.UI.Forms this.mMenToolsComponentsCheck, this.mMenToolsOptions}); this.mMenTools.Name = "mMenTools"; - this.mMenTools.Size = new System.Drawing.Size(47, 20); + this.mMenTools.Size = new System.Drawing.Size(48, 20); this.mMenTools.Text = "&Tools"; // // mMenToolsSSHTransfer @@ -713,7 +713,7 @@ namespace mRemoteNG.UI.Forms this.cmbQuickConnect, this.btnQuickConnect, this.btnConnections}); - this.tsQuickConnect.Location = new System.Drawing.Point(179, 0); + this.tsQuickConnect.Location = new System.Drawing.Point(274, 0); this.tsQuickConnect.MaximumSize = new System.Drawing.Size(0, 25); this.tsQuickConnect.Name = "tsQuickConnect"; this.tsQuickConnect.Size = new System.Drawing.Size(387, 25); @@ -772,14 +772,14 @@ namespace mRemoteNG.UI.Forms this.cMenExtAppsToolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.cMenToolbarShowText}); this.cMenExtAppsToolbar.Name = "cMenToolbar"; - this.cMenExtAppsToolbar.Size = new System.Drawing.Size(128, 26); + this.cMenExtAppsToolbar.Size = new System.Drawing.Size(129, 26); // // cMenToolbarShowText // this.cMenToolbarShowText.Checked = true; this.cMenToolbarShowText.CheckState = System.Windows.Forms.CheckState.Checked; this.cMenToolbarShowText.Name = "cMenToolbarShowText"; - this.cMenToolbarShowText.Size = new System.Drawing.Size(127, 22); + this.cMenToolbarShowText.Size = new System.Drawing.Size(128, 22); this.cMenToolbarShowText.Text = "Show Text"; this.cMenToolbarShowText.Click += new System.EventHandler(this.cMenToolbarShowText_Click); // diff --git a/mRemoteV1/UI/Forms/frmMain.cs b/mRemoteV1/UI/Forms/frmMain.cs index aa65f6afb..5f0684d3f 100644 --- a/mRemoteV1/UI/Forms/frmMain.cs +++ b/mRemoteV1/UI/Forms/frmMain.cs @@ -7,11 +7,14 @@ using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using System.Collections.Generic; +using System.Linq; using mRemoteNG.App; using mRemoteNG.Config; +using mRemoteNG.Config.Putty; using mRemoteNG.Config.Settings; using mRemoteNG.Connection; using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; using mRemoteNG.Messages; using mRemoteNG.Themes; using mRemoteNG.Tools; @@ -39,6 +42,7 @@ namespace mRemoteNG.UI.Forms private ConnectionInfo _selectedConnection; private SystemMenu _systemMenu; private MiscTools.Fullscreen _fullscreen; + private ConnectionTreeWindow ConnectionTreeWindow { get; set; } @@ -123,11 +127,8 @@ namespace mRemoteNG.UI.Forms #endregion #region Startup & Shutdown - private void frmMain_Load(object sender, EventArgs e) { - - // Create gui config load and save objects var settingsLoader = new SettingsLoader(this); settingsLoader.LoadSettings(); @@ -139,12 +140,9 @@ namespace mRemoteNG.UI.Forms fpChainedWindowHandle = NativeMethods.SetClipboardViewer(Handle); - Runtime.MessageCollector = new MessageCollector(Windows.errorsForm); + Runtime.MessageCollector = new MessageCollector(Windows.ErrorsForm); Runtime.WindowList = new WindowList(); - Windows.treePanel.Focus(); - ConnectionTree.TreeView = Windows.treeForm.tvConnections; - if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.GetStartupConnectionFileName())) { Runtime.NewConnections(Runtime.GetStartupConnectionFileName()); @@ -153,10 +151,13 @@ namespace mRemoteNG.UI.Forms Runtime.LoadConnections(); if (!Runtime.IsConnectionsFileLoaded) { - Application.Exit(); - return ; + //Application.Exit(); + //return ; } - Config.Putty.Sessions.StartWatcher(); + + Windows.TreePanel.Focus(); + + PuttySessionsManager.Instance.StartWatcher(); if (Settings.Default.StartupComponentsCheck) { Windows.Show(WindowType.ComponentsCheck); @@ -168,7 +169,9 @@ namespace mRemoteNG.UI.Forms AddSysMenuItems(); Microsoft.Win32.SystemEvents.DisplaySettingsChanged += DisplayChanged; Opacity = 1; - } + + ConnectionTreeWindow = Windows.TreeForm; + } private void ApplySpecialSettingsForPortableVersion() { @@ -421,9 +424,10 @@ namespace mRemoteNG.UI.Forms { var extA = (ExternalTool)((ToolStripButton)sender).Tag; - if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession) + var selectedTreeNode = Windows.TreeForm.SelectedNode; + if (selectedTreeNode.GetTreeNodeType() == TreeNodeType.Connection | selectedTreeNode.GetTreeNodeType() == TreeNodeType.PuttySession) { - extA.Start((ConnectionInfo)ConnectionTree.SelectedNode.Tag); + extA.Start(selectedTreeNode); } else { @@ -452,8 +456,9 @@ namespace mRemoteNG.UI.Forms #region Menu #region File private void mMenFile_DropDownOpening(Object sender, EventArgs e) - { - if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Root) + { + var selectedNodeType = ConnectionTreeWindow.SelectedNode?.GetTreeNodeType(); + if (selectedNodeType == TreeNodeType.Root) { mMenFileNewConnection.Enabled = true; mMenFileNewFolder.Enabled = true; @@ -466,7 +471,7 @@ namespace mRemoteNG.UI.Forms mMenFileDuplicate.Text = Language.strMenuDuplicate; mMenReconnectAll.Text = Language.strMenuReconnectAll; } - else if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Container) + else if (selectedNodeType == TreeNodeType.Container) { mMenFileNewConnection.Enabled = true; mMenFileNewFolder.Enabled = true; @@ -480,7 +485,7 @@ namespace mRemoteNG.UI.Forms mMenReconnectAll.Text = Language.strMenuReconnectAll; } - else if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Connection) + else if (selectedNodeType == TreeNodeType.Connection) { mMenFileNewConnection.Enabled = true; mMenFileNewFolder.Enabled = true; @@ -493,7 +498,7 @@ namespace mRemoteNG.UI.Forms mMenFileDuplicate.Text = Language.strMenuDuplicateConnection; mMenReconnectAll.Text = Language.strMenuReconnectAll; } - else if ((ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttyRoot) || (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession)) + else if (selectedNodeType == TreeNodeType.PuttyRoot || selectedNodeType == TreeNodeType.PuttySession) { mMenFileNewConnection.Enabled = false; mMenFileNewFolder.Enabled = false; @@ -523,14 +528,14 @@ namespace mRemoteNG.UI.Forms private void mMenFileNewConnection_Click(object sender, EventArgs e) { - Windows.treeForm.AddConnection(); - Runtime.SaveConnectionsBG(); + ConnectionTreeWindow.AddConnection(); + Runtime.SaveConnectionsAsync(); } private void mMenFileNewFolder_Click(object sender, EventArgs e) { - Windows.treeForm.AddFolder(); - Runtime.SaveConnectionsBG(); + ConnectionTreeWindow.AddFolder(); + Runtime.SaveConnectionsAsync(); } private void mMenFileNew_Click(object sender, EventArgs e) @@ -574,20 +579,20 @@ namespace mRemoteNG.UI.Forms private void mMenFileDelete_Click(object sender, EventArgs e) { - ConnectionTree.DeleteSelectedNode(); - Runtime.SaveConnectionsBG(); + ConnectionTreeWindow.DeleteSelectedNode(); + Runtime.SaveConnectionsAsync(); } private void mMenFileRename_Click(object sender, EventArgs e) { - ConnectionTree.StartRenameSelectedNode(); - Runtime.SaveConnectionsBG(); + ConnectionTreeWindow.RenameSelectedNode(); + Runtime.SaveConnectionsAsync(); } private void mMenFileDuplicate_Click(object sender, EventArgs e) { - ConnectionTreeNode.CloneNode(ConnectionTree.SelectedNode); - Runtime.SaveConnectionsBG(); + ConnectionTreeWindow.DuplicateSelectedNode(); + Runtime.SaveConnectionsAsync(); } private void mMenReconnectAll_Click(object sender, EventArgs e) @@ -612,7 +617,7 @@ namespace mRemoteNG.UI.Forms foreach (var i in ICList) { i.Protocol.Close(); - Runtime.OpenConnection(i.Info, ConnectionInfo.Force.DoNotJump); + ConnectionInitiator.OpenConnection(i.Info, ConnectionInfo.Force.DoNotJump); } // throw it on the garbage collector @@ -622,8 +627,14 @@ namespace mRemoteNG.UI.Forms } private void mMenFileImportFromFile_Click(object sender, EventArgs e) - { - Import.ImportFromFile(Windows.treeForm.tvConnections.Nodes[0], Windows.treeForm.tvConnections.SelectedNode); + { + var selectedNode = ConnectionTreeWindow.SelectedNode; + ContainerInfo importDestination; + if (selectedNode == null) + importDestination = Runtime.ConnectionTreeModel.RootNodes.First(); + else + importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent; + Import.ImportFromFile(importDestination); } private void mMenFileImportFromActiveDirectory_Click(object sender, EventArgs e) @@ -638,7 +649,7 @@ namespace mRemoteNG.UI.Forms private void mMenFileExport_Click(object sender, EventArgs e) { - Export.ExportToFile(Windows.treeForm.tvConnections.Nodes[0], Windows.treeForm.tvConnections.SelectedNode); + Export.ExportToFile(Windows.TreeForm.SelectedNode, Runtime.ConnectionTreeModel); } private void mMenFileExit_Click(object sender, EventArgs e) @@ -650,10 +661,10 @@ namespace mRemoteNG.UI.Forms #region View private void mMenView_DropDownOpening(object sender, EventArgs e) { - mMenViewConnections.Checked = !Windows.treeForm.IsHidden; - mMenViewConfig.Checked = !Windows.configForm.IsHidden; - mMenViewErrorsAndInfos.Checked = !Windows.errorsForm.IsHidden; - mMenViewScreenshotManager.Checked = !Windows.screenshotForm.IsHidden; + mMenViewConnections.Checked = !Windows.TreeForm.IsHidden; + mMenViewConfig.Checked = !Windows.ConfigForm.IsHidden; + mMenViewErrorsAndInfos.Checked = !Windows.ErrorsForm.IsHidden; + mMenViewScreenshotManager.Checked = !Windows.ScreenshotForm.IsHidden; mMenViewExtAppsToolbar.Checked = tsExternalTools.Visible; mMenViewQuickConnectToolbar.Checked = tsQuickConnect.Visible; @@ -680,12 +691,12 @@ namespace mRemoteNG.UI.Forms { if (mMenViewConnections.Checked == false) { - Windows.treePanel.Show(pnlDock); + Windows.TreePanel.Show(pnlDock); mMenViewConnections.Checked = true; } else { - Windows.treePanel.Hide(); + Windows.TreePanel.Hide(); mMenViewConnections.Checked = false; } } @@ -694,12 +705,12 @@ namespace mRemoteNG.UI.Forms { if (mMenViewConfig.Checked == false) { - Windows.configPanel.Show(pnlDock); + Windows.ConfigPanel.Show(pnlDock); mMenViewConfig.Checked = true; } else { - Windows.configPanel.Hide(); + Windows.ConfigPanel.Hide(); mMenViewConfig.Checked = false; } } @@ -708,12 +719,12 @@ namespace mRemoteNG.UI.Forms { if (mMenViewErrorsAndInfos.Checked == false) { - Windows.errorsPanel.Show(pnlDock); + Windows.ErrorsPanel.Show(pnlDock); mMenViewErrorsAndInfos.Checked = true; } else { - Windows.errorsPanel.Hide(); + Windows.ErrorsPanel.Hide(); mMenViewErrorsAndInfos.Checked = false; } } @@ -722,31 +733,31 @@ namespace mRemoteNG.UI.Forms { if (mMenViewScreenshotManager.Checked == false) { - Windows.screenshotPanel.Show(pnlDock); + Windows.ScreenshotPanel.Show(pnlDock); mMenViewScreenshotManager.Checked = true; } else { - Windows.screenshotPanel.Hide(); + Windows.ScreenshotPanel.Hide(); mMenViewScreenshotManager.Checked = false; } } private void mMenViewJumpToConnectionsConfig_Click(object sender, EventArgs e) { - if (pnlDock.ActiveContent == Windows.treePanel) + if (pnlDock.ActiveContent == Windows.TreePanel) { - Windows.configForm.Activate(); + Windows.ConfigForm.Activate(); } else { - Windows.treeForm.Activate(); + Windows.TreeForm.Activate(); } } private void mMenViewJumpToErrorsInfos_Click(object sender, EventArgs e) { - Windows.errorsForm.Activate(); + Windows.ErrorsForm.Activate(); } private void mMenViewResetLayout_Click(object sender, EventArgs e) @@ -883,7 +894,7 @@ namespace mRemoteNG.UI.Forms return ; } cmbQuickConnect.Add(connectionInfo); - Runtime.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); + ConnectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump); } catch (Exception ex) { @@ -956,48 +967,16 @@ namespace mRemoteNG.UI.Forms #region Connections DropDown private void btnConnections_DropDownOpening(object sender, EventArgs e) { - btnConnections.DropDownItems.Clear(); - foreach (TreeNode treeNode in Windows.treeForm.tvConnections.Nodes) - { - AddNodeToMenu(treeNode.Nodes, btnConnections); - } + btnConnections.DropDownItems.Clear(); + var menuItemsConverter = new ConnectionsTreeToMenuItemsConverter + { + MouseUpEventHandler = ConnectionsMenuItem_MouseUp + }; + + ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionTreeModel).ToArray(); + btnConnections.DropDownItems.AddRange(rootMenuItems); } - - private static void AddNodeToMenu(TreeNodeCollection treeNodeCollection, ToolStripDropDownItem toolStripMenuItem) - { - try - { - foreach (TreeNode treeNode in treeNodeCollection) - { - var menuItem = new ToolStripMenuItem(); - menuItem.Text = treeNode.Text; - menuItem.Tag = treeNode; - - if (ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Container) - { - menuItem.Image = Resources.Folder; - menuItem.Tag = treeNode.Tag; - - toolStripMenuItem.DropDownItems.Add(menuItem); - AddNodeToMenu(treeNode.Nodes, menuItem); - } - else if (ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(treeNode) == TreeNodeType.PuttySession) - { - menuItem.Image = Windows.treeForm.imgListTree.Images[treeNode.ImageIndex]; - menuItem.Tag = treeNode.Tag; - - toolStripMenuItem.DropDownItems.Add(menuItem); - } - - menuItem.MouseUp += ConnectionsMenuItem_MouseUp; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionMessage("frmMain.AddNodeToMenu() failed", ex, MessageClass.ErrorMsg, true); - } - } - + private static void ConnectionsMenuItem_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) @@ -1005,7 +984,7 @@ namespace mRemoteNG.UI.Forms var tag = ((ToolStripMenuItem)sender).Tag as ConnectionInfo; if (tag != null) { - Runtime.OpenConnection(tag); + ConnectionInitiator.OpenConnection(tag); } } } @@ -1141,7 +1120,7 @@ namespace mRemoteNG.UI.Forms var tab = w.TabController.SelectedTab; var ifc = (InterfaceControl)tab.Tag; ifc.Protocol.Focus(); - ((ConnectionWindow) ifc.FindForm())?.RefreshIC(); + ((ConnectionWindow) ifc.FindForm())?.RefreshInterfaceController(); } private void pnlDock_ActiveDocumentChanged(object sender, EventArgs e) @@ -1255,9 +1234,9 @@ namespace mRemoteNG.UI.Forms tabController.SelectedIndex = newIndex; } #endif -#endregion + #endregion -#region Screen Stuff + #region Screen Stuff private void DisplayChanged(object sender, EventArgs e) { ResetSysMenuItems(); @@ -1283,9 +1262,9 @@ namespace mRemoteNG.UI.Forms _systemMenu.InsertMenuItem(_systemMenu.SystemMenuHandle, 0, SystemMenu.Flags.MF_POPUP | SystemMenu.Flags.MF_BYPOSITION, popMen, Language.strSendTo); _systemMenu.InsertMenuItem(_systemMenu.SystemMenuHandle, 1, SystemMenu.Flags.MF_BYPOSITION | SystemMenu.Flags.MF_SEPARATOR, IntPtr.Zero, null); } -#endregion + #endregion -#region Events + #region Events public delegate void clipboardchangeEventHandler(); public static event clipboardchangeEventHandler clipboardchange { @@ -1298,6 +1277,6 @@ namespace mRemoteNG.UI.Forms clipboardchangeEvent = (clipboardchangeEventHandler)Delegate.Remove(clipboardchangeEvent, value); } } -#endregion + #endregion } } diff --git a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs index 4ddc5b209..2ced90b14 100644 --- a/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs +++ b/mRemoteV1/UI/Window/ActiveDirectoryImportWindow.cs @@ -1,7 +1,9 @@ using System; +using System.Linq; using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using mRemoteNG.App; +using mRemoteNG.Container; namespace mRemoteNG.UI.Window @@ -27,22 +29,26 @@ namespace mRemoteNG.UI.Window EnableDisableImportButton(); } - public void btnImport_Click(Object sender, EventArgs e) + public void btnImport_Click(object sender, EventArgs e) { - Import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath); + var selectedNode = Windows.TreeForm.SelectedNode; + ContainerInfo importDestination; + if (selectedNode != null) + importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent; + else + importDestination = Runtime.ConnectionTreeModel.RootNodes.First(); + Import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath, importDestination); DialogResult = DialogResult.OK; Close(); } - static public void txtDomain_PreviewKeyDown(Object sender, PreviewKeyDownEventArgs e) + public static void txtDomain_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.KeyCode == Keys.Enter) - { e.IsInputKey = true; - } } - public void txtDomain_KeyDown(Object sender, KeyEventArgs e) + public void txtDomain_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { @@ -51,7 +57,7 @@ namespace mRemoteNG.UI.Window } } - public void btnChangeDomain_Click(Object sender, EventArgs e) + public void btnChangeDomain_Click(object sender, EventArgs e) { ChangeDomain(); } diff --git a/mRemoteV1/UI/Window/ConfigWindow.cs b/mRemoteV1/UI/Window/ConfigWindow.cs index 6568804c1..e5af9612f 100644 --- a/mRemoteV1/UI/Window/ConfigWindow.cs +++ b/mRemoteV1/UI/Window/ConfigWindow.cs @@ -16,6 +16,7 @@ using System.Windows.Forms; using mRemoteNG.Connection.Protocol; using mRemoteNG.Container; using mRemoteNG.Security; +using mRemoteNG.Themes; using mRemoteNG.UI.Controls.FilteredPropertyGrid; using WeifenLuo.WinFormsUI.Docking; @@ -40,6 +41,7 @@ namespace mRemoteNG.UI.Window private ToolStripSeparator ToolStripSeparator1; private FilteredPropertyGrid pGrid; + private AbstractConnectionInfoData _selectedNode; private void InitializeComponent() { @@ -209,7 +211,7 @@ namespace mRemoteNG.UI.Window } } } - + public bool InheritanceVisible { get @@ -227,7 +229,7 @@ namespace mRemoteNG.UI.Window } } } - + public bool DefaultPropertiesVisible { get @@ -245,7 +247,7 @@ namespace mRemoteNG.UI.Window } } } - + public bool DefaultInheritanceVisible { get { return btnShowDefaultInheritance.Checked; } @@ -307,7 +309,7 @@ namespace mRemoteNG.UI.Window return base.ProcessCmdKey(ref msg, keyData); } } - + private void FindChildGridItems(GridItem item, ref List gridItems) { gridItems.Add(item); @@ -320,7 +322,7 @@ namespace mRemoteNG.UI.Window } } } - + private bool ContainsGridItemProperty(List gridItems) { foreach (var item in gridItems) @@ -332,7 +334,7 @@ namespace mRemoteNG.UI.Window } return false; } - + private GridItem FindPreviousGridItemProperty(List gridItems, GridItem startItem) { if (gridItems.Count == 0 || startItem == null) @@ -377,7 +379,7 @@ namespace mRemoteNG.UI.Window return null; return gridItems[previousIndex]; } - + private GridItem FindNextGridItemProperty(List gridItems, GridItem startItem) { if (gridItems.Count == 0 || startItem == null) @@ -422,7 +424,7 @@ namespace mRemoteNG.UI.Window return null; return gridItems[nextIndex]; } - + public void SetPropertyGridObject(object Obj) { try @@ -475,14 +477,7 @@ namespace mRemoteNG.UI.Window pGrid.SelectedObject = Obj; btnShowProperties.Enabled = true; - if (((ContainerInfo) Obj).Parent.Parent != null) - { - btnShowInheritance.Enabled = true; - } - else - { - btnShowInheritance.Enabled = false; - } + btnShowInheritance.Enabled = ((ContainerInfo) Obj).Parent != null; btnShowDefaultProperties.Enabled = false; btnShowDefaultInheritance.Enabled = false; btnIcon.Enabled = true; @@ -610,9 +605,10 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConfigPropertyGridObjectFailed + Environment.NewLine + ex.Message, true); } } - - public void pGrid_SelectedObjectChanged() + + public void pGrid_SelectedObjectChanged(AbstractConnectionInfoData selectedObject) { + _selectedNode = selectedObject; ShowHideGridItems(); } #endregion @@ -630,7 +626,7 @@ namespace mRemoteNG.UI.Window TabText = Language.strMenuConfig; propertyGridContextMenuShowHelpText.Text = Language.strMenuShowHelpText; } - + private void ApplyTheme() { pGrid.BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; @@ -697,21 +693,21 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConfigUiLoadFailed + Environment.NewLine + ex.Message, true); } } - + private void Config_Load(object sender, EventArgs e) { ApplyLanguage(); - Themes.ThemeManager.ThemeChanged += ApplyTheme; + ThemeManager.ThemeChanged += ApplyTheme; ApplyTheme(); AddToolStripItems(); pGrid.HelpVisible = Settings.Default.ShowConfigHelpText; } - + private void Config_SystemColorsChanged(object sender, EventArgs e) { AddToolStripItems(); } - + private void pGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { try @@ -720,7 +716,7 @@ namespace mRemoteNG.UI.Window UpdateRootInfoNode(e); UpdateInheritanceNode(); ShowHideGridItems(); - Runtime.SaveConnectionsBG(); + Runtime.SaveConnectionsAsync(); } catch (Exception ex) { @@ -730,6 +726,7 @@ namespace mRemoteNG.UI.Window private void UpdateConnectionInfoNode(PropertyValueChangedEventArgs e) { + Debug.WriteLine("update config"); var selectedGridObject = pGrid.SelectedObject as ConnectionInfo; if (selectedGridObject == null) return; if (e.ChangedItem.Label == Language.strPropertyNameProtocol) @@ -738,7 +735,6 @@ namespace mRemoteNG.UI.Window } else if (e.ChangedItem.Label == Language.strPropertyNameName) { - Windows.treeForm.tvConnections.SelectedNode.Text = Convert.ToString(selectedGridObject.Name); if (Settings.Default.SetHostnameLikeDisplayName) { var connectionInfo = selectedGridObject; @@ -763,39 +759,36 @@ namespace mRemoteNG.UI.Window private void UpdateRootInfoNode(PropertyValueChangedEventArgs e) { - var o = pGrid.SelectedObject as RootNodeInfo; - if (o != null) + var rootInfo = pGrid.SelectedObject as RootNodeInfo; + if (rootInfo == null) return; + if (e.ChangedItem.PropertyDescriptor == null) return; + switch (e.ChangedItem.PropertyDescriptor.Name) { - var rootInfo = o; - if (e.ChangedItem.PropertyDescriptor != null) - switch (e.ChangedItem.PropertyDescriptor.Name) + case "Password": + if (rootInfo.Password) { - case "Password": - if (rootInfo.Password) - { - string passwordName; - if (Settings.Default.UseSQLServer) - passwordName = Language.strSQLServer.TrimEnd(':'); - else - passwordName = Path.GetFileName(Runtime.GetStartupConnectionFileName()); + string passwordName; + if (Settings.Default.UseSQLServer) + passwordName = Language.strSQLServer.TrimEnd(':'); + else + passwordName = Path.GetFileName(Runtime.GetStartupConnectionFileName()); - var password = MiscTools.PasswordDialog(passwordName); - if (password.Length == 0) - rootInfo.Password = false; - else - rootInfo.PasswordString = password.ConvertToUnsecureString(); - } - break; - case "Name": - break; + var password = MiscTools.PasswordDialog(passwordName); + if (password.Length == 0) + rootInfo.Password = false; + else + rootInfo.PasswordString = password.ConvertToUnsecureString(); } + break; + case "Name": + break; } } private void UpdateInheritanceNode() { if (!(pGrid.SelectedObject is DefaultConnectionInheritance)) return; - DefaultConnectionInheritance.Instance.SaveTo(Settings.Default, (a)=>"InhDefault"+a); + DefaultConnectionInheritance.Instance.SaveTo(Settings.Default, (a)=>"InhDefault"+a); } private void pGrid_PropertySortChanged(object sender, EventArgs e) @@ -803,13 +796,12 @@ namespace mRemoteNG.UI.Window if (pGrid.PropertySort == PropertySort.CategorizedAlphabetical) pGrid.PropertySort = PropertySort.Categorized; } - + private void ShowHideGridItems() { try { var strHide = new List(); - if (pGrid.SelectedObject is RootNodeInfo) { var rootInfo = (RootNodeInfo)pGrid.SelectedObject; @@ -872,7 +864,6 @@ namespace mRemoteNG.UI.Window else if (pGrid.SelectedObject is ConnectionInfo) { var conI = (ConnectionInfo)pGrid.SelectedObject; - switch (conI.Protocol) { case ProtocolType.RDP: @@ -1449,7 +1440,7 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConfigPropertyGridHideItemsFailed + Environment.NewLine + ex.Message, true); } } - + private void btnShowProperties_Click(object sender, EventArgs e) { if (pGrid.SelectedObject is ConnectionInfoInheritance) @@ -1460,7 +1451,7 @@ namespace mRemoteNG.UI.Window InheritanceVisible = false; DefaultPropertiesVisible = false; DefaultInheritanceVisible = false; - SetPropertyGridObject((RootNodeInfo)Windows.treeForm.tvConnections.SelectedNode.Tag); + SetPropertyGridObject((RootNodeInfo)_selectedNode); } else { @@ -1478,10 +1469,10 @@ namespace mRemoteNG.UI.Window InheritanceVisible = false; DefaultPropertiesVisible = false; DefaultInheritanceVisible = false; - SetPropertyGridObject((RootNodeInfo)Windows.treeForm.tvConnections.SelectedNode.Tag); + SetPropertyGridObject((RootNodeInfo)_selectedNode); } } - + private void btnShowDefaultProperties_Click(object sender, EventArgs e) { if (!(pGrid.SelectedObject is RootNodeInfo) && !(pGrid.SelectedObject is ConnectionInfoInheritance)) return; @@ -1491,7 +1482,7 @@ namespace mRemoteNG.UI.Window DefaultInheritanceVisible = false; SetPropertyGridObject(DefaultConnectionInfo.Instance); } - + private void btnShowInheritance_Click(object sender, EventArgs e) { if (!(pGrid.SelectedObject is ConnectionInfo)) return; @@ -1501,7 +1492,7 @@ namespace mRemoteNG.UI.Window DefaultInheritanceVisible = false; SetPropertyGridObject(((ConnectionInfo)pGrid.SelectedObject).Inheritance); } - + private void btnShowDefaultInheritance_Click(object sender, EventArgs e) { if (pGrid.SelectedObject is RootNodeInfo || pGrid.SelectedObject is ConnectionInfo) @@ -1513,12 +1504,12 @@ namespace mRemoteNG.UI.Window SetPropertyGridObject(DefaultConnectionInheritance.Instance); } } - + private void btnHostStatus_Click(object sender, EventArgs e) { SetHostStatus(pGrid.SelectedObject); } - + private void btnIcon_Click(object sender, MouseEventArgs e) { try @@ -1547,7 +1538,7 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConfigPropertyGridButtonIconClickFailed + Environment.NewLine + ex.Message, true); } } - + private void IconMenu_Click(object sender, EventArgs e) { try @@ -1581,7 +1572,7 @@ namespace mRemoteNG.UI.Window connectionInfo.Icon = iconName; pGrid.Refresh(); - Runtime.SaveConnectionsBG(); + Runtime.SaveConnectionsAsync(); } catch (Exception ex) { @@ -1593,7 +1584,7 @@ namespace mRemoteNG.UI.Window #region Host Status (Ping) private string HostName; private Thread pThread; - + private void CheckHostAlive() { var pingSender = new Ping(); @@ -1624,7 +1615,7 @@ namespace mRemoteNG.UI.Window } } } - + delegate void ShowStatusImageCB(Image image); private void ShowStatusImage(Image image) { @@ -1639,7 +1630,7 @@ namespace mRemoteNG.UI.Window btnHostStatus.Tag = "checkfinished"; } } - + public void SetHostStatus(object connectionInfo) { try @@ -1686,7 +1677,7 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddExceptionMessage("UI.Window.Config.propertyGridContextMenu_Opening() failed.", ex, MessageClass.ErrorMsg, true); } } - + private void propertyGridContextMenuReset_Click(object sender, EventArgs e) { try @@ -1702,12 +1693,12 @@ namespace mRemoteNG.UI.Window Runtime.MessageCollector.AddExceptionMessage("UI.Window.Config.propertyGridContextMenuReset_Click() failed.", ex, MessageClass.ErrorMsg, true); } } - + private void propertyGridContextMenuShowHelpText_Click(object sender, EventArgs e) { propertyGridContextMenuShowHelpText.Checked = !propertyGridContextMenuShowHelpText.Checked; } - + private void propertyGridContextMenuShowHelpText_CheckedChanged(object sender, EventArgs e) { Settings.Default.ShowConfigHelpText = propertyGridContextMenuShowHelpText.Checked; diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs index 461d684bd..82865b44a 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.Designer.cs @@ -1,13 +1,10 @@ -using mRemoteNG.My; - namespace mRemoteNG.UI.Window { public partial class ConnectionTreeWindow : BaseWindow { #region Windows Form Designer generated code - private System.ComponentModel.Container components = null; internal System.Windows.Forms.TextBox txtSearch; internal System.Windows.Forms.Panel pnlConnections; internal System.Windows.Forms.ImageList imgListTree; @@ -15,492 +12,208 @@ namespace mRemoteNG.UI.Window internal System.Windows.Forms.ToolStripMenuItem mMenView; internal System.Windows.Forms.ToolStripMenuItem mMenViewExpandAllFolders; internal System.Windows.Forms.ToolStripMenuItem mMenViewCollapseAllFolders; - internal System.Windows.Forms.ContextMenuStrip cMenTree; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeAddConnection; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeAddFolder; - internal System.Windows.Forms.ToolStripSeparator cMenTreeSep1; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnect; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptions; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptionsConnectToConsoleSession; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptionsNoCredentials; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptionsConnectInFullscreen; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeDisconnect; - internal System.Windows.Forms.ToolStripSeparator cMenTreeSep2; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeToolsTransferFile; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeToolsSort; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeToolsSortAscending; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeToolsSortDescending; - internal System.Windows.Forms.ToolStripSeparator cMenTreeSep3; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeRename; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeDelete; - internal System.Windows.Forms.ToolStripSeparator cMenTreeSep4; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeMoveUp; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeMoveDown; internal System.Windows.Forms.PictureBox PictureBox1; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeToolsExternalApps; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeDuplicate; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptionsChoosePanelBeforeConnecting; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeConnectWithOptionsDontConnectToConsoleSession; internal System.Windows.Forms.ToolStripMenuItem mMenSortAscending; internal System.Windows.Forms.ToolStripMenuItem mMenAddConnection; internal System.Windows.Forms.ToolStripMenuItem mMenAddFolder; public System.Windows.Forms.TreeView tvConnections; + public BrightIdeasSoftware.TreeListView olvConnections; private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - this.Load += new System.EventHandler(Tree_Load); - System.Windows.Forms.TreeNode TreeNode1 = new System.Windows.Forms.TreeNode("Connections"); - this.tvConnections = new System.Windows.Forms.TreeView(); - this.tvConnections.BeforeLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tvConnections_BeforeLabelEdit); - this.tvConnections.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tvConnections_AfterLabelEdit); - this.tvConnections.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvConnections_AfterSelect); - this.tvConnections.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvConnections_NodeMouseClick); - this.tvConnections.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(tvConnections_NodeMouseDoubleClick); - this.tvConnections.MouseMove += new System.Windows.Forms.MouseEventHandler(this.tvConnections_MouseMove); - this.tvConnections.DragDrop += new System.Windows.Forms.DragEventHandler(tvConnections_DragDrop); - this.tvConnections.DragEnter += new System.Windows.Forms.DragEventHandler(tvConnections_DragEnter); - this.tvConnections.DragOver += new System.Windows.Forms.DragEventHandler(tvConnections_DragOver); - this.tvConnections.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.tvConnections_ItemDrag); - this.tvConnections.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.tvConnections_KeyPress); - this.tvConnections.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tvConnections_KeyDown); - this.cMenTree = new System.Windows.Forms.ContextMenuStrip(this.components); - this.cMenTree.Opening += new System.ComponentModel.CancelEventHandler(this.cMenTree_DropDownOpening); - this.cMenTreeConnect = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnect.Click += new System.EventHandler(cMenTreeConnect_Click); - this.cMenTreeConnectWithOptions = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsConnectToConsoleSession = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsConnectToConsoleSession.Click += new System.EventHandler(cMenTreeConnectWithOptionsConnectToConsoleSession_Click); - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Click += new System.EventHandler(cMenTreeConnectWithOptionsDontConnectToConsoleSession_Click); - this.cMenTreeConnectWithOptionsConnectInFullscreen = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsConnectInFullscreen.Click += new System.EventHandler(cMenTreeConnectWithOptionsConnectInFullscreen_Click); - this.cMenTreeConnectWithOptionsNoCredentials = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsNoCredentials.Click += new System.EventHandler(cMenTreeConnectWithOptionsNoCredentials_Click); - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Click += new System.EventHandler(cMenTreeConnectWithOptionsChoosePanelBeforeConnecting_Click); - this.cMenTreeDisconnect = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeDisconnect.Click += new System.EventHandler(this.cMenTreeDisconnect_Click); - this.cMenTreeSep1 = new System.Windows.Forms.ToolStripSeparator(); - this.cMenTreeToolsExternalApps = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeToolsTransferFile = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeToolsTransferFile.Click += new System.EventHandler(cMenTreeToolsTransferFile_Click); - this.cMenTreeSep2 = new System.Windows.Forms.ToolStripSeparator(); - this.cMenTreeDuplicate = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeDuplicate.Click += new System.EventHandler(cMenTreeDuplicate_Click); - this.cMenTreeRename = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeRename.Click += new System.EventHandler(cMenTreeRename_Click); - this.cMenTreeDelete = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeDelete.Click += new System.EventHandler(cMenTreeDelete_Click); - this.cMenTreeSep3 = new System.Windows.Forms.ToolStripSeparator(); - this.cMenTreeImport = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeImportFile = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeImportFile.Click += new System.EventHandler(cMenTreeImportFile_Click); - this.cMenTreeImportActiveDirectory = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeImportActiveDirectory.Click += new System.EventHandler(cMenTreeImportActiveDirectory_Click); - this.cMenTreeImportPortScan = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeImportPortScan.Click += new System.EventHandler(cMenTreeImportPortScan_Click); - this.cMenTreeExportFile = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeExportFile.Click += new System.EventHandler(cMenTreeExportFile_Click); - this.cMenTreeSep4 = new System.Windows.Forms.ToolStripSeparator(); - this.cMenTreeAddConnection = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeAddConnection.Click += new System.EventHandler(this.cMenTreeAddConnection_Click); - this.cMenTreeAddFolder = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeAddFolder.Click += new System.EventHandler(this.cMenTreeAddFolder_Click); - this.ToolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.cMenTreeToolsSort = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeToolsSortAscending = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeToolsSortAscending.Click += new System.EventHandler(this.cMenTreeToolsSortAscending_Click); - this.cMenTreeToolsSortDescending = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeToolsSortDescending.Click += new System.EventHandler(this.cMenTreeToolsSortDescending_Click); - this.cMenTreeMoveUp = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeMoveUp.Click += new System.EventHandler(cMenTreeMoveUp_Click); - this.cMenTreeMoveDown = new System.Windows.Forms.ToolStripMenuItem(); - this.cMenTreeMoveDown.Click += new System.EventHandler(cMenTreeMoveDown_Click); - this.imgListTree = new System.Windows.Forms.ImageList(this.components); - this.pnlConnections = new System.Windows.Forms.Panel(); - this.PictureBox1 = new System.Windows.Forms.PictureBox(); - this.txtSearch = new System.Windows.Forms.TextBox(); - this.txtSearch.GotFocus += new System.EventHandler(this.txtSearch_GotFocus); - this.txtSearch.LostFocus += new System.EventHandler(this.txtSearch_LostFocus); - this.txtSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtSearch_KeyDown); - this.txtSearch.TextChanged += new System.EventHandler(this.txtSearch_TextChanged); - this.msMain = new System.Windows.Forms.MenuStrip(); - this.mMenAddConnection = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenAddConnection.Click += new System.EventHandler(this.cMenTreeAddConnection_Click); - this.mMenAddFolder = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenAddFolder.Click += new System.EventHandler(this.cMenTreeAddFolder_Click); - this.mMenView = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenViewExpandAllFolders = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenViewExpandAllFolders.Click += new System.EventHandler(mMenViewExpandAllFolders_Click); - this.mMenViewCollapseAllFolders = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenViewCollapseAllFolders.Click += new System.EventHandler(this.mMenViewCollapseAllFolders_Click); - this.mMenSortAscending = new System.Windows.Forms.ToolStripMenuItem(); - this.mMenSortAscending.Click += new System.EventHandler(this.mMenSortAscending_Click); - this.cMenTree.SuspendLayout(); - this.pnlConnections.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize) this.PictureBox1).BeginInit(); - this.msMain.SuspendLayout(); - this.SuspendLayout(); - // - //tvConnections - // - this.tvConnections.AllowDrop = true; - this.tvConnections.Anchor = (System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right); - this.tvConnections.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.tvConnections.ContextMenuStrip = this.cMenTree; - this.tvConnections.HideSelection = false; - this.tvConnections.ImageIndex = 0; - this.tvConnections.ImageList = this.imgListTree; - this.tvConnections.LabelEdit = true; - this.tvConnections.Location = new System.Drawing.Point(0, 0); - this.tvConnections.Name = "tvConnections"; - TreeNode1.Name = "nodeRoot"; - TreeNode1.Text = "Connections"; - this.tvConnections.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {TreeNode1}); - this.tvConnections.SelectedImageIndex = 0; - this.tvConnections.Size = new System.Drawing.Size(192, 410); - this.tvConnections.TabIndex = 20; - // - //cMenTree - // - this.cMenTree.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)); - this.cMenTree.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cMenTreeConnect, this.cMenTreeConnectWithOptions, this.cMenTreeDisconnect, this.cMenTreeSep1, this.cMenTreeToolsExternalApps, this.cMenTreeToolsTransferFile, this.cMenTreeSep2, this.cMenTreeDuplicate, this.cMenTreeRename, this.cMenTreeDelete, this.cMenTreeSep3, this.cMenTreeImport, this.cMenTreeExportFile, this.cMenTreeSep4, this.cMenTreeAddConnection, this.cMenTreeAddFolder, this.ToolStripSeparator1, this.cMenTreeToolsSort, this.cMenTreeMoveUp, this.cMenTreeMoveDown}); - this.cMenTree.Name = "cMenTree"; - this.cMenTree.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.cMenTree.Size = new System.Drawing.Size(187, 386); - // - //cMenTreeConnect - // - this.cMenTreeConnect.Image = Resources.Play; - this.cMenTreeConnect.Name = "cMenTreeConnect"; - this.cMenTreeConnect.ShortcutKeys = (System.Windows.Forms.Keys) ((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) - | System.Windows.Forms.Keys.C); - this.cMenTreeConnect.Size = new System.Drawing.Size(186, 22); - this.cMenTreeConnect.Text = "Connect"; - // - //cMenTreeConnectWithOptions - // - this.cMenTreeConnectWithOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cMenTreeConnectWithOptionsConnectToConsoleSession, this.cMenTreeConnectWithOptionsDontConnectToConsoleSession, this.cMenTreeConnectWithOptionsConnectInFullscreen, this.cMenTreeConnectWithOptionsNoCredentials, this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting}); - this.cMenTreeConnectWithOptions.Name = "cMenTreeConnectWithOptions"; - this.cMenTreeConnectWithOptions.Size = new System.Drawing.Size(186, 22); - this.cMenTreeConnectWithOptions.Text = "Connect (with options)"; - // - //cMenTreeConnectWithOptionsConnectToConsoleSession - // - this.cMenTreeConnectWithOptionsConnectToConsoleSession.Image = Resources.monitor_go; - this.cMenTreeConnectWithOptionsConnectToConsoleSession.Name = "cMenTreeConnectWithOptionsConnectToConsoleSession"; - this.cMenTreeConnectWithOptionsConnectToConsoleSession.Size = new System.Drawing.Size(231, 22); - this.cMenTreeConnectWithOptionsConnectToConsoleSession.Text = "Connect to console session"; - // - //cMenTreeConnectWithOptionsDontConnectToConsoleSession - // - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Image = Resources.monitor_delete; - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Name = "cMenTreeConnectWithOptionsDontConnectToConsoleSession"; - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Size = new System.Drawing.Size(231, 22); - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Text = "Don\'t connect to console session"; - this.cMenTreeConnectWithOptionsDontConnectToConsoleSession.Visible = false; - // - //cMenTreeConnectWithOptionsConnectInFullscreen - // - this.cMenTreeConnectWithOptionsConnectInFullscreen.Image = Resources.arrow_out; - this.cMenTreeConnectWithOptionsConnectInFullscreen.Name = "cMenTreeConnectWithOptionsConnectInFullscreen"; - this.cMenTreeConnectWithOptionsConnectInFullscreen.Size = new System.Drawing.Size(231, 22); - this.cMenTreeConnectWithOptionsConnectInFullscreen.Text = "Connect in fullscreen"; - // - //cMenTreeConnectWithOptionsNoCredentials - // - this.cMenTreeConnectWithOptionsNoCredentials.Image = Resources.key_delete; - this.cMenTreeConnectWithOptionsNoCredentials.Name = "cMenTreeConnectWithOptionsNoCredentials"; - this.cMenTreeConnectWithOptionsNoCredentials.Size = new System.Drawing.Size(231, 22); - this.cMenTreeConnectWithOptionsNoCredentials.Text = "Connect without credentials"; - // - //cMenTreeConnectWithOptionsChoosePanelBeforeConnecting - // - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Image = Resources.Panels; - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Name = "cMenTreeConnectWithOptionsChoosePanelBeforeConnecting"; - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Size = new System.Drawing.Size(231, 22); - this.cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Text = "Choose panel before connecting"; - // - //cMenTreeDisconnect - // - this.cMenTreeDisconnect.Image = Resources.Pause; - this.cMenTreeDisconnect.Name = "cMenTreeDisconnect"; - this.cMenTreeDisconnect.Size = new System.Drawing.Size(186, 22); - this.cMenTreeDisconnect.Text = "Disconnect"; - // - //cMenTreeSep1 - // - this.cMenTreeSep1.Name = "cMenTreeSep1"; - this.cMenTreeSep1.Size = new System.Drawing.Size(183, 6); - // - //cMenTreeToolsExternalApps - // - this.cMenTreeToolsExternalApps.Image = Resources.ExtApp; - this.cMenTreeToolsExternalApps.Name = "cMenTreeToolsExternalApps"; - this.cMenTreeToolsExternalApps.Size = new System.Drawing.Size(186, 22); - this.cMenTreeToolsExternalApps.Text = "External Applications"; - // - //cMenTreeToolsTransferFile - // - this.cMenTreeToolsTransferFile.Image = Resources.SSHTransfer; - this.cMenTreeToolsTransferFile.Name = "cMenTreeToolsTransferFile"; - this.cMenTreeToolsTransferFile.Size = new System.Drawing.Size(186, 22); - this.cMenTreeToolsTransferFile.Text = "Transfer File (SSH)"; - // - //cMenTreeSep2 - // - this.cMenTreeSep2.Name = "cMenTreeSep2"; - this.cMenTreeSep2.Size = new System.Drawing.Size(183, 6); - // - //cMenTreeDuplicate - // - this.cMenTreeDuplicate.Image = Resources.page_copy; - this.cMenTreeDuplicate.Name = "cMenTreeDuplicate"; - this.cMenTreeDuplicate.ShortcutKeys = (System.Windows.Forms.Keys) (System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D); - this.cMenTreeDuplicate.Size = new System.Drawing.Size(186, 22); - this.cMenTreeDuplicate.Text = "Duplicate"; - // - //cMenTreeRename - // - this.cMenTreeRename.Image = Resources.Rename; - this.cMenTreeRename.Name = "cMenTreeRename"; - this.cMenTreeRename.ShortcutKeys = System.Windows.Forms.Keys.F2; - this.cMenTreeRename.Size = new System.Drawing.Size(186, 22); - this.cMenTreeRename.Text = "Rename"; - // - //cMenTreeDelete - // - this.cMenTreeDelete.Image = Resources.Delete; - this.cMenTreeDelete.Name = "cMenTreeDelete"; - this.cMenTreeDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete; - this.cMenTreeDelete.Size = new System.Drawing.Size(186, 22); - this.cMenTreeDelete.Text = "Delete"; - // - //cMenTreeSep3 - // - this.cMenTreeSep3.Name = "cMenTreeSep3"; - this.cMenTreeSep3.Size = new System.Drawing.Size(183, 6); - // - //cMenTreeImport - // - this.cMenTreeImport.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cMenTreeImportFile, this.cMenTreeImportActiveDirectory, this.cMenTreeImportPortScan}); - this.cMenTreeImport.Name = "cMenTreeImport"; - this.cMenTreeImport.Size = new System.Drawing.Size(186, 22); - this.cMenTreeImport.Text = "&Import"; - // - //cMenTreeImportFile - // - this.cMenTreeImportFile.Name = "cMenTreeImportFile"; - this.cMenTreeImportFile.Size = new System.Drawing.Size(213, 22); - this.cMenTreeImportFile.Text = "Import from &File..."; - // - //cMenTreeImportActiveDirectory - // - this.cMenTreeImportActiveDirectory.Name = "cMenTreeImportActiveDirectory"; - this.cMenTreeImportActiveDirectory.Size = new System.Drawing.Size(213, 22); - this.cMenTreeImportActiveDirectory.Text = "Import from &Active Directory..."; - // - //cMenTreeImportPortScan - // - this.cMenTreeImportPortScan.Name = "cMenTreeImportPortScan"; - this.cMenTreeImportPortScan.Size = new System.Drawing.Size(213, 22); - this.cMenTreeImportPortScan.Text = "Import from &Port Scan..."; - // - //cMenTreeExportFile - // - this.cMenTreeExportFile.Name = "cMenTreeExportFile"; - this.cMenTreeExportFile.Size = new System.Drawing.Size(186, 22); - this.cMenTreeExportFile.Text = "&Export to File..."; - // - //cMenTreeSep4 - // - this.cMenTreeSep4.Name = "cMenTreeSep4"; - this.cMenTreeSep4.Size = new System.Drawing.Size(183, 6); - // - //cMenTreeAddConnection - // - this.cMenTreeAddConnection.Image = Resources.Connection_Add; - this.cMenTreeAddConnection.Name = "cMenTreeAddConnection"; - this.cMenTreeAddConnection.Size = new System.Drawing.Size(186, 22); - this.cMenTreeAddConnection.Text = "New Connection"; - // - //cMenTreeAddFolder - // - this.cMenTreeAddFolder.Image = Resources.Folder_Add; - this.cMenTreeAddFolder.Name = "cMenTreeAddFolder"; - this.cMenTreeAddFolder.Size = new System.Drawing.Size(186, 22); - this.cMenTreeAddFolder.Text = "New Folder"; - // - //ToolStripSeparator1 - // - this.ToolStripSeparator1.Name = "ToolStripSeparator1"; - this.ToolStripSeparator1.Size = new System.Drawing.Size(183, 6); - // - //cMenTreeToolsSort - // - this.cMenTreeToolsSort.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.cMenTreeToolsSortAscending, this.cMenTreeToolsSortDescending}); - this.cMenTreeToolsSort.Name = "cMenTreeToolsSort"; - this.cMenTreeToolsSort.Size = new System.Drawing.Size(186, 22); - this.cMenTreeToolsSort.Text = "Sort"; - // - //cMenTreeToolsSortAscending - // - this.cMenTreeToolsSortAscending.Image = Resources.Sort_AZ; - this.cMenTreeToolsSortAscending.Name = "cMenTreeToolsSortAscending"; - this.cMenTreeToolsSortAscending.Size = new System.Drawing.Size(157, 22); - this.cMenTreeToolsSortAscending.Text = "Ascending (A-Z)"; - // - //cMenTreeToolsSortDescending - // - this.cMenTreeToolsSortDescending.Image = Resources.Sort_ZA; - this.cMenTreeToolsSortDescending.Name = "cMenTreeToolsSortDescending"; - this.cMenTreeToolsSortDescending.Size = new System.Drawing.Size(157, 22); - this.cMenTreeToolsSortDescending.Text = "Descending (Z-A)"; - // - //cMenTreeMoveUp - // - this.cMenTreeMoveUp.Image = Resources.Arrow_Up; - this.cMenTreeMoveUp.Name = "cMenTreeMoveUp"; - this.cMenTreeMoveUp.ShortcutKeys = (System.Windows.Forms.Keys) (System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Up); - this.cMenTreeMoveUp.Size = new System.Drawing.Size(186, 22); - this.cMenTreeMoveUp.Text = "Move up"; - // - //cMenTreeMoveDown - // - this.cMenTreeMoveDown.Image = Resources.Arrow_Down; - this.cMenTreeMoveDown.Name = "cMenTreeMoveDown"; - this.cMenTreeMoveDown.ShortcutKeys = (System.Windows.Forms.Keys) (System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Down); - this.cMenTreeMoveDown.Size = new System.Drawing.Size(186, 22); - this.cMenTreeMoveDown.Text = "Move down"; - // - //imgListTree - // - this.imgListTree.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; - this.imgListTree.ImageSize = new System.Drawing.Size(16, 16); - this.imgListTree.TransparentColor = System.Drawing.Color.Transparent; - // - //pnlConnections - // - this.pnlConnections.Anchor = (System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right); - this.pnlConnections.Controls.Add(this.PictureBox1); - this.pnlConnections.Controls.Add(this.txtSearch); - this.pnlConnections.Controls.Add(this.tvConnections); - this.pnlConnections.Location = new System.Drawing.Point(0, 25); - this.pnlConnections.Name = "pnlConnections"; - this.pnlConnections.Size = new System.Drawing.Size(192, 428); - this.pnlConnections.TabIndex = 9; - // - //PictureBox1 - // - this.PictureBox1.Anchor = (System.Windows.Forms.AnchorStyles) (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left); - this.PictureBox1.Image = Resources.Search; - this.PictureBox1.Location = new System.Drawing.Point(2, 412); - this.PictureBox1.Name = "PictureBox1"; - this.PictureBox1.Size = new System.Drawing.Size(16, 16); - this.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PictureBox1.TabIndex = 1; - this.PictureBox1.TabStop = false; - // - //txtSearch - // - this.txtSearch.Anchor = (System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right); - this.txtSearch.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.txtSearch.ForeColor = System.Drawing.SystemColors.GrayText; - this.txtSearch.Location = new System.Drawing.Point(19, 413); - this.txtSearch.Name = "txtSearch"; - this.txtSearch.Size = new System.Drawing.Size(171, 13); - this.txtSearch.TabIndex = 30; - this.txtSearch.TabStop = false; - this.txtSearch.Text = "Search"; - // - //msMain - // - this.msMain.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)); - this.msMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.mMenAddConnection, this.mMenAddFolder, this.mMenView, this.mMenSortAscending}); - this.msMain.Location = new System.Drawing.Point(0, 0); - this.msMain.Name = "msMain"; - this.msMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.msMain.ShowItemToolTips = true; - this.msMain.Size = new System.Drawing.Size(192, 24); - this.msMain.TabIndex = 10; - this.msMain.Text = "MenuStrip1"; - // - //mMenAddConnection - // - this.mMenAddConnection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.mMenAddConnection.Image = Resources.Connection_Add; - this.mMenAddConnection.Name = "mMenAddConnection"; - this.mMenAddConnection.Size = new System.Drawing.Size(28, 20); - // - //mMenAddFolder - // - this.mMenAddFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.mMenAddFolder.Image = Resources.Folder_Add; - this.mMenAddFolder.Name = "mMenAddFolder"; - this.mMenAddFolder.Size = new System.Drawing.Size(28, 20); - // - //mMenView - // - this.mMenView.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.mMenView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.mMenViewExpandAllFolders, this.mMenViewCollapseAllFolders}); - this.mMenView.Image = Resources.View; - this.mMenView.Name = "mMenView"; - this.mMenView.Size = new System.Drawing.Size(28, 20); - this.mMenView.Text = "&View"; - // - //mMenViewExpandAllFolders - // - this.mMenViewExpandAllFolders.Image = Resources.Expand; - this.mMenViewExpandAllFolders.Name = "mMenViewExpandAllFolders"; - this.mMenViewExpandAllFolders.Size = new System.Drawing.Size(161, 22); - this.mMenViewExpandAllFolders.Text = "Expand all folders"; - // - //mMenViewCollapseAllFolders - // - this.mMenViewCollapseAllFolders.Image = Resources.Collapse; - this.mMenViewCollapseAllFolders.Name = "mMenViewCollapseAllFolders"; - this.mMenViewCollapseAllFolders.Size = new System.Drawing.Size(161, 22); - this.mMenViewCollapseAllFolders.Text = "Collapse all folders"; - // - //mMenSortAscending - // - this.mMenSortAscending.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.mMenSortAscending.Image = Resources.Sort_AZ; - this.mMenSortAscending.Name = "mMenSortAscending"; - this.mMenSortAscending.Size = new System.Drawing.Size(28, 20); - // - //Tree - // - this.ClientSize = new System.Drawing.Size(192, 453); - this.Controls.Add(this.msMain); - this.Controls.Add(this.pnlConnections); - this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)); - this.HideOnClose = true; - this.Icon = Resources.Root_Icon; - this.Name = "Tree"; - this.TabText = "Connections"; - this.Text = "Connections"; - this.cMenTree.ResumeLayout(false); - this.pnlConnections.ResumeLayout(false); - this.pnlConnections.PerformLayout(); - ((System.ComponentModel.ISupportInitialize) this.PictureBox1).EndInit(); - this.msMain.ResumeLayout(false); - this.msMain.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - + this.components = new System.ComponentModel.Container(); + this.olvConnections = new BrightIdeasSoftware.TreeListView(); + this.olvNameColumn = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.imgListTree = new System.Windows.Forms.ImageList(this.components); + this.pnlConnections = new System.Windows.Forms.Panel(); + this.PictureBox1 = new System.Windows.Forms.PictureBox(); + this.txtSearch = new System.Windows.Forms.TextBox(); + this.msMain = new System.Windows.Forms.MenuStrip(); + this.mMenAddConnection = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenAddFolder = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenView = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenViewExpandAllFolders = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenViewCollapseAllFolders = new System.Windows.Forms.ToolStripMenuItem(); + this.mMenSortAscending = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.olvConnections)).BeginInit(); + this.pnlConnections.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).BeginInit(); + this.msMain.SuspendLayout(); + this.SuspendLayout(); + // + // olvConnections + // + this.olvConnections.AllColumns.Add(this.olvNameColumn); + this.olvConnections.AllowDrop = true; + this.olvConnections.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.olvConnections.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.olvConnections.CellEditUseWholeCell = false; + this.olvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.olvNameColumn}); + this.olvConnections.Cursor = System.Windows.Forms.Cursors.Default; + this.olvConnections.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + this.olvConnections.HideSelection = false; + this.olvConnections.IsSimpleDragSource = true; + this.olvConnections.IsSimpleDropSink = true; + this.olvConnections.LabelEdit = true; + this.olvConnections.Location = new System.Drawing.Point(0, 0); + this.olvConnections.MultiSelect = false; + this.olvConnections.Name = "olvConnections"; + this.olvConnections.SelectedBackColor = System.Drawing.SystemColors.Highlight; + this.olvConnections.SelectedForeColor = System.Drawing.SystemColors.HighlightText; + this.olvConnections.ShowGroups = false; + this.olvConnections.Size = new System.Drawing.Size(192, 410); + this.olvConnections.SmallImageList = this.imgListTree; + this.olvConnections.TabIndex = 20; + this.olvConnections.UnfocusedSelectedBackColor = System.Drawing.SystemColors.Highlight; + this.olvConnections.UnfocusedSelectedForeColor = System.Drawing.SystemColors.HighlightText; + this.olvConnections.UseCompatibleStateImageBehavior = false; + this.olvConnections.View = System.Windows.Forms.View.Details; + this.olvConnections.VirtualMode = true; + // + // olvNameColumn + // + this.olvNameColumn.AspectName = "Name"; + this.olvNameColumn.FillsFreeSpace = true; + this.olvNameColumn.IsButton = true; + // + // imgListTree + // + this.imgListTree.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; + this.imgListTree.ImageSize = new System.Drawing.Size(16, 16); + this.imgListTree.TransparentColor = System.Drawing.Color.Transparent; + // + // pnlConnections + // + this.pnlConnections.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlConnections.Controls.Add(this.PictureBox1); + this.pnlConnections.Controls.Add(this.txtSearch); + this.pnlConnections.Controls.Add(this.olvConnections); + this.pnlConnections.Location = new System.Drawing.Point(0, 25); + this.pnlConnections.Name = "pnlConnections"; + this.pnlConnections.Size = new System.Drawing.Size(192, 428); + this.pnlConnections.TabIndex = 9; + // + // PictureBox1 + // + this.PictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.PictureBox1.Image = global::mRemoteNG.Resources.Search; + this.PictureBox1.Location = new System.Drawing.Point(2, 412); + this.PictureBox1.Name = "PictureBox1"; + this.PictureBox1.Size = new System.Drawing.Size(16, 16); + this.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.PictureBox1.TabIndex = 1; + this.PictureBox1.TabStop = false; + // + // txtSearch + // + this.txtSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtSearch.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txtSearch.ForeColor = System.Drawing.SystemColors.GrayText; + this.txtSearch.Location = new System.Drawing.Point(19, 413); + this.txtSearch.Name = "txtSearch"; + this.txtSearch.Size = new System.Drawing.Size(171, 15); + this.txtSearch.TabIndex = 30; + this.txtSearch.TabStop = false; + this.txtSearch.Text = "Search"; + this.txtSearch.TextChanged += new System.EventHandler(this.txtSearch_TextChanged); + this.txtSearch.GotFocus += new System.EventHandler(this.txtSearch_GotFocus); + this.txtSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtSearch_KeyDown); + this.txtSearch.LostFocus += new System.EventHandler(this.txtSearch_LostFocus); + // + // msMain + // + this.msMain.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.msMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mMenAddConnection, + this.mMenAddFolder, + this.mMenView, + this.mMenSortAscending}); + this.msMain.Location = new System.Drawing.Point(0, 0); + this.msMain.Name = "msMain"; + this.msMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.msMain.ShowItemToolTips = true; + this.msMain.Size = new System.Drawing.Size(192, 24); + this.msMain.TabIndex = 10; + this.msMain.Text = "MenuStrip1"; + // + // mMenAddConnection + // + this.mMenAddConnection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.mMenAddConnection.Image = global::mRemoteNG.Resources.Connection_Add; + this.mMenAddConnection.Name = "mMenAddConnection"; + this.mMenAddConnection.Size = new System.Drawing.Size(28, 20); + this.mMenAddConnection.Click += new System.EventHandler(this.cMenTreeAddConnection_Click); + // + // mMenAddFolder + // + this.mMenAddFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.mMenAddFolder.Image = global::mRemoteNG.Resources.Folder_Add; + this.mMenAddFolder.Name = "mMenAddFolder"; + this.mMenAddFolder.Size = new System.Drawing.Size(28, 20); + this.mMenAddFolder.Click += new System.EventHandler(this.cMenTreeAddFolder_Click); + // + // mMenView + // + this.mMenView.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.mMenView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mMenViewExpandAllFolders, + this.mMenViewCollapseAllFolders}); + this.mMenView.Image = global::mRemoteNG.Resources.View; + this.mMenView.Name = "mMenView"; + this.mMenView.Size = new System.Drawing.Size(28, 20); + this.mMenView.Text = "&View"; + // + // mMenViewExpandAllFolders + // + this.mMenViewExpandAllFolders.Image = global::mRemoteNG.Resources.Expand; + this.mMenViewExpandAllFolders.Name = "mMenViewExpandAllFolders"; + this.mMenViewExpandAllFolders.Size = new System.Drawing.Size(172, 22); + this.mMenViewExpandAllFolders.Text = "Expand all folders"; + // + // mMenViewCollapseAllFolders + // + this.mMenViewCollapseAllFolders.Image = global::mRemoteNG.Resources.Collapse; + this.mMenViewCollapseAllFolders.Name = "mMenViewCollapseAllFolders"; + this.mMenViewCollapseAllFolders.Size = new System.Drawing.Size(172, 22); + this.mMenViewCollapseAllFolders.Text = "Collapse all folders"; + // + // mMenSortAscending + // + this.mMenSortAscending.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.mMenSortAscending.Image = global::mRemoteNG.Resources.Sort_AZ; + this.mMenSortAscending.Name = "mMenSortAscending"; + this.mMenSortAscending.Size = new System.Drawing.Size(28, 20); + // + // ConnectionTreeWindow + // + this.ClientSize = new System.Drawing.Size(192, 453); + this.Controls.Add(this.msMain); + this.Controls.Add(this.pnlConnections); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.HideOnClose = true; + this.Icon = global::mRemoteNG.Resources.Root_Icon; + this.Name = "ConnectionTreeWindow"; + this.TabText = "Connections"; + this.Text = "Connections"; + this.Load += new System.EventHandler(this.Tree_Load); + ((System.ComponentModel.ISupportInitialize)(this.olvConnections)).EndInit(); + this.pnlConnections.ResumeLayout(false); + this.pnlConnections.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).EndInit(); + this.msMain.ResumeLayout(false); + this.msMain.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + } - internal System.Windows.Forms.ToolStripMenuItem cMenTreeImport; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeExportFile; - internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator1; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeImportFile; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeImportActiveDirectory; - internal System.Windows.Forms.ToolStripMenuItem cMenTreeImportPortScan; #endregion - } + + private System.ComponentModel.IContainer components; + private BrightIdeasSoftware.OLVColumn olvNameColumn; + } } diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs index eaad57931..c8696311c 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.cs @@ -1,12 +1,21 @@ using mRemoteNG.App; using mRemoteNG.Connection; -using mRemoteNG.Connection.Protocol; using mRemoteNG.Container; -using mRemoteNG.Messages; using mRemoteNG.Tree; using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; using System.Drawing; +using System.Linq; using System.Windows.Forms; +using BrightIdeasSoftware; +using mRemoteNG.Config.Putty; +using mRemoteNG.Root.PuttySessions; +using mRemoteNG.Tools; +using mRemoteNG.Tree.Root; +using mRemoteNG.UI.Controls; using WeifenLuo.WinFormsUI.Docking; @@ -14,135 +23,379 @@ namespace mRemoteNG.UI.Window { public partial class ConnectionTreeWindow { - #region Form Stuff + private ConnectionTreeModel _connectionTreeModel; + private readonly ConnectionTreeDragAndDropHandler _dragAndDropHandler = new ConnectionTreeDragAndDropHandler(); + private NodeSearcher _nodeSearcher; + private readonly ConnectionContextMenu _contextMenu = new ConnectionContextMenu(); + private readonly PuttySessionsManager _puttySessionsManager = PuttySessionsManager.Instance; - private void Tree_Load(object sender, EventArgs e) - { - ApplyLanguage(); - - Themes.ThemeManager.ThemeChanged += ApplyTheme; - ApplyTheme(); - - txtSearch.Multiline = true; - txtSearch.MinimumSize = new Size(0, 14); - txtSearch.Size = new Size(txtSearch.Size.Width, 14); - txtSearch.Multiline = false; - } - - private void ApplyLanguage() - { - Text = Language.strConnections; - TabText = Language.strConnections; - - mMenAddConnection.ToolTipText = Language.strAddConnection; - mMenAddFolder.ToolTipText = Language.strAddFolder; - mMenView.ToolTipText = Language.strMenuView.Replace("&", ""); - mMenViewExpandAllFolders.Text = Language.strExpandAllFolders; - mMenViewCollapseAllFolders.Text = Language.strCollapseAllFolders; - mMenSortAscending.ToolTipText = Language.strSortAsc; - - cMenTreeConnect.Text = Language.strConnect; - cMenTreeConnectWithOptions.Text = Language.strConnectWithOptions; - cMenTreeConnectWithOptionsConnectToConsoleSession.Text = Language.strConnectToConsoleSession; - cMenTreeConnectWithOptionsDontConnectToConsoleSession.Text = Language.strDontConnectToConsoleSessionMenuItem; - cMenTreeConnectWithOptionsConnectInFullscreen.Text = Language.strConnectInFullscreen; - cMenTreeConnectWithOptionsNoCredentials.Text = Language.strConnectNoCredentials; - cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Text = Language.strChoosePanelBeforeConnecting; - cMenTreeDisconnect.Text = Language.strMenuDisconnect; - - cMenTreeToolsExternalApps.Text = Language.strMenuExternalTools; - cMenTreeToolsTransferFile.Text = Language.strMenuTransferFile; - - cMenTreeDuplicate.Text = Language.strDuplicate; - cMenTreeRename.Text = Language.strRename; - cMenTreeDelete.Text = Language.strMenuDelete; - - cMenTreeImport.Text = Language.strImportMenuItem; - cMenTreeImportFile.Text = Language.strImportFromFileMenuItem; - cMenTreeImportActiveDirectory.Text = Language.strImportAD; - cMenTreeImportPortScan.Text = Language.strImportPortScan; - cMenTreeExportFile.Text = Language.strExportToFileMenuItem; - - cMenTreeAddConnection.Text = Language.strAddConnection; - cMenTreeAddFolder.Text = Language.strAddFolder; - - cMenTreeToolsSort.Text = Language.strSort; - cMenTreeToolsSortAscending.Text = Language.strSortAsc; - cMenTreeToolsSortDescending.Text = Language.strSortDesc; - cMenTreeMoveUp.Text = Language.strMoveUp; - cMenTreeMoveDown.Text = Language.strMoveDown; - - txtSearch.Text = Language.strSearchPrompt; - } + public ConnectionInfo SelectedNode => (ConnectionInfo) olvConnections.SelectedObject; + + public ConnectionTreeModel ConnectionTreeModel + { + get { return _connectionTreeModel; } + set + { + _connectionTreeModel = value; + PopulateTreeView(); + } + } - private void ApplyTheme() - { - msMain.BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; - msMain.ForeColor = Themes.ThemeManager.ActiveTheme.ToolbarTextColor; - tvConnections.BackColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelBackgroundColor; - tvConnections.ForeColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTextColor; - tvConnections.LineColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTreeLineColor; - BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; - txtSearch.BackColor = Themes.ThemeManager.ActiveTheme.SearchBoxBackgroundColor; - txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; - } - #endregion - - #region Public Methods public ConnectionTreeWindow(DockContent panel) { WindowType = WindowType.Tree; DockPnl = panel; InitializeComponent(); - FillImageList(); - - DescriptionTooltip = new ToolTip(); - DescriptionTooltip.InitialDelay = 300; - DescriptionTooltip.ReshowDelay = 0; - } - - public void InitialRefresh() - { - tvConnections_AfterSelect(tvConnections, new TreeViewEventArgs(tvConnections.SelectedNode, TreeViewAction.ByMouse)); + + FillImageList(); + LinkModelToView(); + SetupDropSink(); + SetEventHandlers(); } + + private void FillImageList() + { + try + { + imgListTree.Images.Add(Resources.Root); + imgListTree.Images.SetKeyName(0, "Root"); + imgListTree.Images.Add(Resources.Folder); + imgListTree.Images.SetKeyName(1, "Folder"); + imgListTree.Images.Add(Resources.Play); + imgListTree.Images.SetKeyName(2, "Play"); + imgListTree.Images.Add(Resources.Pause); + imgListTree.Images.SetKeyName(3, "Pause"); + imgListTree.Images.Add(Resources.PuttySessions); + imgListTree.Images.SetKeyName(4, "PuttySessions"); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("FillImageList (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void LinkModelToView() + { + olvNameColumn.AspectGetter = item => ((ConnectionInfo)item).Name; + olvNameColumn.ImageGetter = ConnectionImageGetter; + olvConnections.CanExpandGetter = item => + { + var itemAsContainer = item as ContainerInfo; + return itemAsContainer?.Children.Count > 0; + }; + olvConnections.ChildrenGetter = item => ((ContainerInfo)item).Children; + olvConnections.ContextMenuStrip = _contextMenu; + } + + private void SetupDropSink() + { + var dropSink = (SimpleDropSink)olvConnections.DropSink; + dropSink.CanDropBetween = true; + } + + private object ConnectionImageGetter(object rowObject) + { + if (rowObject is RootPuttySessionsNodeInfo) return "PuttySessions"; + if (rowObject is RootNodeInfo) return "Root"; + if (rowObject is ContainerInfo) return "Folder"; + var connection = rowObject as ConnectionInfo; + if (connection == null) return ""; + return connection.OpenConnections.Count > 0 ? "Play" : "Pause"; + } + + private void SetEventHandlers() + { + SetTreeEventHandlers(); + SetContextMenuEventHandlers(); + SetMenuEventHandlers(); + } + + private void SetTreeEventHandlers() + { + olvConnections.Collapsed += (sender, args) => + { + var container = args.Model as ContainerInfo; + if (container != null) + container.IsExpanded = false; + }; + olvConnections.Expanded += (sender, args) => + { + var container = args.Model as ContainerInfo; + if (container != null) + container.IsExpanded = true; + }; + olvConnections.BeforeLabelEdit += tvConnections_BeforeLabelEdit; + olvConnections.AfterLabelEdit += tvConnections_AfterLabelEdit; + olvConnections.SelectionChanged += tvConnections_AfterSelect; + olvConnections.CellClick += tvConnections_NodeMouseSingleClick; + olvConnections.CellClick += tvConnections_NodeMouseDoubleClick; + olvConnections.CellToolTipShowing += tvConnections_CellToolTipShowing; + olvConnections.ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop; + olvConnections.ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; + olvConnections.KeyDown += tvConnections_KeyDown; + olvConnections.KeyPress += tvConnections_KeyPress; + } + + private void SetContextMenuEventHandlers() + { + _contextMenu.Opening += (sender, args) => _contextMenu.ShowHideTreeContextMenuItems(SelectedNode); + _contextMenu.ConnectClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.DoNotJump); + }; + _contextMenu.ConnectToConsoleSessionClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); + }; + _contextMenu.DontConnectToConsoleSessionClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); + }; + _contextMenu.ConnectInFullscreenClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); + }; + _contextMenu.ConnectWithNoCredentialsClick += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.NoCredentials); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.NoCredentials); + }; + _contextMenu.ChoosePanelBeforeConnectingClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + ConnectionInitiator.OpenConnection(selectedNodeAsContainer, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); + else + ConnectionInitiator.OpenConnection(SelectedNode, ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); + }; + _contextMenu.DisconnectClicked += (sender, args) => DisconnectConnection(SelectedNode); + _contextMenu.TransferFileClicked += (sender, args) => SshTransferFile(); + _contextMenu.DuplicateClicked += (sender, args) => DuplicateSelectedNode(); + _contextMenu.RenameClicked += (sender, args) => RenameSelectedNode(); + _contextMenu.DeleteClicked += (sender, args) => DeleteSelectedNode(); + _contextMenu.ImportFileClicked += (sender, args) => + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo ?? SelectedNode.Parent; + Import.ImportFromFile(selectedNodeAsContainer, true); + }; + _contextMenu.ImportActiveDirectoryClicked += (sender, args) => Windows.Show(WindowType.ActiveDirectoryImport); + _contextMenu.ImportPortScanClicked += (sender, args) => Windows.Show(WindowType.PortScan); + _contextMenu.ExportFileClicked += (sender, args) => Export.ExportToFile(SelectedNode, Runtime.ConnectionTreeModel); + _contextMenu.AddConnectionClicked += cMenTreeAddConnection_Click; + _contextMenu.AddFolderClicked += cMenTreeAddFolder_Click; + _contextMenu.SortAscendingClicked += (sender, args) => SortNodesRecursive(SelectedNode, ListSortDirection.Ascending); + _contextMenu.SortDescendingClicked += (sender, args) => SortNodesRecursive(SelectedNode, ListSortDirection.Descending); + _contextMenu.MoveUpClicked += cMenTreeMoveUp_Click; + _contextMenu.MoveDownClicked += cMenTreeMoveDown_Click; + _contextMenu.ExternalToolClicked += (sender, args) => StartExternalApp((ExternalTool)((ToolStripMenuItem)sender).Tag); + } + + private void SetMenuEventHandlers() + { + mMenViewExpandAllFolders.Click += (sender, args) => olvConnections.ExpandAll(); + mMenViewCollapseAllFolders.Click += (sender, args) => + { + olvConnections.CollapseAll(); + olvConnections.Expand(GetRootConnectionNode()); + }; + mMenSortAscending.Click += (sender, args) => SortNodesRecursive(GetRootConnectionNode(), ListSortDirection.Ascending); + } + + private void PopulateTreeView() + { + olvConnections.SetObjects(ConnectionTreeModel.RootNodes); + SetModelUpdateHandlers(); + _nodeSearcher = new NodeSearcher(ConnectionTreeModel); + ExpandPreviouslyOpenedFolders(); + ExpandRootConnectionNode(); + OpenConnectionsFromLastSession(); + } + + private void SetModelUpdateHandlers() + { + _puttySessionsManager.PuttySessionsCollectionChanged += (sender, args) => RefreshTreeObjects(GetRootPuttyNodes().ToList()); + ConnectionTreeModel.CollectionChanged += HandleCollectionChanged; + ConnectionTreeModel.PropertyChanged += HandleCollectionPropertyChanged; + } + + private void HandleCollectionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + //TODO for some reason property changed events are getting triggered twice for each changed property. should be just once. cant find source of duplication + if (propertyChangedEventArgs.PropertyName != "Name") return; + var senderAsConnectionInfo = sender as ConnectionInfo; + if (senderAsConnectionInfo != null) + RefreshTreeObject(senderAsConnectionInfo); + } + + private void ExpandRootConnectionNode() + { + var rootConnectionNode = GetRootConnectionNode(); + olvConnections.InvokeExpand(rootConnectionNode); + } + + private RootNodeInfo GetRootConnectionNode() + { + return (RootNodeInfo)olvConnections.Roots.Cast().First(item => item is RootNodeInfo); + } + + private IEnumerable GetRootPuttyNodes() + { + return olvConnections.Objects.OfType(); + } + + #region Form Stuff + private void Tree_Load(object sender, EventArgs e) + { + ApplyLanguage(); + Themes.ThemeManager.ThemeChanged += ApplyTheme; + ApplyTheme(); + + txtSearch.Multiline = true; + txtSearch.MinimumSize = new Size(0, 14); + txtSearch.Size = new Size(txtSearch.Size.Width, 14); + txtSearch.Multiline = false; + } + + private void ApplyLanguage() + { + Text = Language.strConnections; + TabText = Language.strConnections; + + mMenAddConnection.ToolTipText = Language.strAddConnection; + mMenAddFolder.ToolTipText = Language.strAddFolder; + mMenView.ToolTipText = Language.strMenuView.Replace("&", ""); + mMenViewExpandAllFolders.Text = Language.strExpandAllFolders; + mMenViewCollapseAllFolders.Text = Language.strCollapseAllFolders; + mMenSortAscending.ToolTipText = Language.strSortAsc; + + txtSearch.Text = Language.strSearchPrompt; + } + + private void ApplyTheme() + { + msMain.BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; + msMain.ForeColor = Themes.ThemeManager.ActiveTheme.ToolbarTextColor; + olvConnections.BackColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelBackgroundColor; + olvConnections.ForeColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTextColor; + //tvConnections.LineColor = Themes.ThemeManager.ActiveTheme.ConnectionsPanelTreeLineColor; + BackColor = Themes.ThemeManager.ActiveTheme.ToolbarBackgroundColor; + txtSearch.BackColor = Themes.ThemeManager.ActiveTheme.SearchBoxBackgroundColor; + txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; + } #endregion - #region Public Properties - private ToolTip DescriptionTooltip {get; set;} - #endregion - + public void ExpandPreviouslyOpenedFolders() + { + var containerList = ConnectionTreeModel.GetRecursiveChildList(GetRootConnectionNode()).OfType(); + var previouslyExpandedNodes = containerList.Where(container => container.IsExpanded); + olvConnections.ExpandedObjects = previouslyExpandedNodes; + olvConnections.InvokeRebuildAll(true); + } + + public void OpenConnectionsFromLastSession() + { + if (!Settings.Default.OpenConsFromLastSession || Settings.Default.NoReconnect) return; + var connectionInfoList = GetRootConnectionNode().GetRecursiveChildList().Where(node => !(node is ContainerInfo)); + var previouslyOpenedConnections = connectionInfoList.Where(item => item.PleaseConnect); + foreach (var connectionInfo in previouslyOpenedConnections) + { + ConnectionInitiator.OpenConnection(connectionInfo); + } + } + + public void EnsureRootNodeVisible() + { + olvConnections.EnsureModelVisible(GetRootConnectionNode()); + } + + public void DuplicateSelectedNode() + { + var newNode = SelectedNode.Clone(); + newNode.Parent.SetChildBelow(newNode, SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + public void RenameSelectedNode() + { + olvConnections.SelectedItem.BeginEdit(); + Runtime.SaveConnectionsAsync(); + } + + public void DeleteSelectedNode() + { + if (SelectedNode is RootNodeInfo || SelectedNode is PuttySessionInfo) return; + if (!UserConfirmsDeletion()) return; + ConnectionTreeModel.DeleteNode(SelectedNode); + Runtime.SaveConnectionsAsync(); + } + + private bool UserConfirmsDeletion() + { + var selectedNodeAsContainer = SelectedNode as ContainerInfo; + if (selectedNodeAsContainer != null) + return selectedNodeAsContainer.HasChildren() + ? UserConfirmsNonEmptyFolderDeletion() + : UserConfirmsEmptyFolderDeletion(); + return UserConfirmsConnectionDeletion(); + } + + private bool UserConfirmsEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolder, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsNonEmptyFolderDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeFolderNotEmpty, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool UserConfirmsConnectionDeletion() + { + var messagePrompt = string.Format(Language.strConfirmDeleteNodeConnection, SelectedNode.Name); + return PromptUser(messagePrompt); + } + + private bool PromptUser(string promptMessage) + { + var msgBoxResponse = MessageBox.Show(promptMessage, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + return (msgBoxResponse == DialogResult.Yes); + } + #region Private Methods - private void FillImageList() + private void tvConnections_BeforeLabelEdit(object sender, LabelEditEventArgs e) + { + _contextMenu.DisableShortcutKeys(); + } + + private void tvConnections_AfterLabelEdit(object sender, LabelEditEventArgs e) { try { - imgListTree.Images.Add(Resources.Root); - imgListTree.Images.Add(Resources.Folder); - imgListTree.Images.Add(Resources.Play); - imgListTree.Images.Add(Resources.Pause); - imgListTree.Images.Add(Resources.PuttySessions); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("FillImageList (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e) - { - cMenTreeDelete.ShortcutKeys = Keys.None; - } - - private void tvConnections_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) - { - try - { - cMenTreeDelete.ShortcutKeys = Keys.Delete; - - ConnectionTree.FinishRenameSelectedNode(e.Label); - Windows.configForm.pGrid_SelectedObjectChanged(); - ShowHideTreeContextMenuItems(e.Node); - Runtime.SaveConnectionsBG(); + _contextMenu.EnableShortcutKeys(); + ConnectionTreeModel.RenameNode(SelectedNode, e.Label); + Windows.ConfigForm.pGrid_SelectedObjectChanged(SelectedNode); + Runtime.SaveConnectionsAsync(); } catch (Exception ex) { @@ -150,686 +403,239 @@ namespace mRemoteNG.UI.Window } } - private void tvConnections_AfterSelect(object sender, TreeViewEventArgs e) + private void tvConnections_AfterSelect(object sender, EventArgs e) { - try - { - if ((ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.Connection) || (ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.PuttySession)) - { - Windows.configForm.SetPropertyGridObject(e.Node.Tag); - } - else if (ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.Container) - { - Windows.configForm.SetPropertyGridObject((ContainerInfo) e.Node.Tag); - } - else if ((ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.Root) || (ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.PuttyRoot)) - { - Windows.configForm.SetPropertyGridObject(e.Node.Tag); - } - else - { - return; - } + try + { + Windows.ConfigForm.SetPropertyGridObject(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); + } + } - Windows.configForm.pGrid_SelectedObjectChanged(); - ShowHideTreeContextMenuItems(e.Node); + private void tvConnections_NodeMouseSingleClick(object sender, CellClickEventArgs e) + { + try + { + if (e.ClickCount > 1) return; + var clickedNode = e.Model as ConnectionInfo; - Runtime.LastSelected = ConnectionTreeNode.GetConstantID(e.Node); - } - catch (Exception ex) + if (clickedNode == null) return; + if (clickedNode.GetTreeNodeType() != TreeNodeType.Connection && clickedNode.GetTreeNodeType() != TreeNodeType.PuttySession) return; + if (Settings.Default.SingleClickOnConnectionOpensIt) + ConnectionInitiator.OpenConnection(SelectedNode); + + if (Settings.Default.SingleClickSwitchesToOpenConnection) + ConnectionInitiator.SwitchToOpenConnection(SelectedNode); + } + catch (Exception ex) + { + Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); + } + } + + private void tvConnections_NodeMouseDoubleClick(object sender, CellClickEventArgs e) + { + if (e.ClickCount < 2) return; + var clickedNode = e.Model as ConnectionInfo; + + if (clickedNode?.GetTreeNodeType() == TreeNodeType.Connection | + clickedNode?.GetTreeNodeType() == TreeNodeType.PuttySession) { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex); + ConnectionInitiator.OpenConnection(SelectedNode); } } - private void tvConnections_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + private void tvConnections_CellToolTipShowing(object sender, ToolTipShowingEventArgs e) { try { - ShowHideTreeContextMenuItems(tvConnections.SelectedNode); - tvConnections.SelectedNode = e.Node; - - if (e.Button == MouseButtons.Left) - { - if (Settings.Default.SingleClickOnConnectionOpensIt && - (ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.Connection | - ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.PuttySession)) - { - Runtime.OpenConnection(); - } - - if (Settings.Default.SingleClickSwitchesToOpenConnection && ConnectionTreeNode.GetNodeType(e.Node) == TreeNodeType.Connection) - { - Runtime.SwitchToOpenConnection((ConnectionInfo)e.Node.Tag); - } - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_NodeMouseClick (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private static void tvConnections_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) - { - if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Connection | - ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession) - { - Runtime.OpenConnection(); - } - } - - private void tvConnections_MouseMove(object sender, MouseEventArgs e) - { - try - { - ConnectionTree.SetNodeToolTip(e, DescriptionTooltip); + var nodeProducingTooltip = (ConnectionInfo) e.Model; + e.Text = nodeProducingTooltip.Description; } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_MouseMove (UI.Window.ConnectionTreeWindow) failed", ex); } } - - private static void EnableMenuItemsRecursive(ToolStripItemCollection items, bool enable = true) - { - foreach (ToolStripItem item in items) - { - var menuItem = item as ToolStripMenuItem; - if (menuItem == null) - { - continue; - } - menuItem.Enabled = enable; - if (menuItem.HasDropDownItems) - { - EnableMenuItemsRecursive(menuItem.DropDownItems, enable); - } - } - } - - private void ShowHideTreeContextMenuItems(TreeNode selectedNode) - { - if (selectedNode == null) - { - return ; - } - - try - { - cMenTree.Enabled = true; - EnableMenuItemsRecursive(cMenTree.Items); - - if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.Connection) - { - ConnectionInfo connectionInfo = (ConnectionInfo)selectedNode.Tag; - - if (connectionInfo.OpenConnections.Count == 0) - { - cMenTreeDisconnect.Enabled = false; - } - - if (!(connectionInfo.Protocol == ProtocolType.SSH1 | - connectionInfo.Protocol == ProtocolType.SSH2)) - { - cMenTreeToolsTransferFile.Enabled = false; - } - - if (!(connectionInfo.Protocol == ProtocolType.RDP | connectionInfo.Protocol == ProtocolType.ICA)) - { - cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - } - - if (connectionInfo.Protocol == ProtocolType.IntApp) - { - cMenTreeConnectWithOptionsNoCredentials.Enabled = false; - } - } - else if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.PuttySession) - { - PuttySessionInfo puttySessionInfo = (PuttySessionInfo)selectedNode.Tag; - - cMenTreeAddConnection.Enabled = false; - cMenTreeAddFolder.Enabled = false; - - if (puttySessionInfo.OpenConnections.Count == 0) - { - cMenTreeDisconnect.Enabled = false; - } - - if (!(puttySessionInfo.Protocol == ProtocolType.SSH1 | puttySessionInfo.Protocol == ProtocolType.SSH2)) - { - cMenTreeToolsTransferFile.Enabled = false; - } - - cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - cMenTreeToolsSort.Enabled = false; - cMenTreeDuplicate.Enabled = false; - cMenTreeRename.Enabled = false; - cMenTreeDelete.Enabled = false; - cMenTreeMoveUp.Enabled = false; - cMenTreeMoveDown.Enabled = false; - } - else if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.Container) - { - cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - cMenTreeDisconnect.Enabled = false; - - int openConnections = 0; - foreach (TreeNode node in selectedNode.Nodes) - { - if (node.Tag is ConnectionInfo) - { - var connectionInfo = (ConnectionInfo)node.Tag; - openConnections = openConnections + connectionInfo.OpenConnections.Count; - } - } - if (openConnections == 0) - { - cMenTreeDisconnect.Enabled = false; - } - - cMenTreeToolsTransferFile.Enabled = false; - cMenTreeToolsExternalApps.Enabled = false; - } - else if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.Root) - { - cMenTreeConnect.Enabled = false; - cMenTreeConnectWithOptions.Enabled = false; - cMenTreeConnectWithOptionsConnectInFullscreen.Enabled = false; - cMenTreeConnectWithOptionsConnectToConsoleSession.Enabled = false; - cMenTreeConnectWithOptionsChoosePanelBeforeConnecting.Enabled = false; - cMenTreeDisconnect.Enabled = false; - cMenTreeToolsTransferFile.Enabled = false; - cMenTreeToolsExternalApps.Enabled = false; - cMenTreeDuplicate.Enabled = false; - cMenTreeDelete.Enabled = false; - cMenTreeMoveUp.Enabled = false; - cMenTreeMoveDown.Enabled = false; - } - else if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.PuttyRoot) - { - cMenTreeAddConnection.Enabled = false; - cMenTreeAddFolder.Enabled = false; - cMenTreeConnect.Enabled = false; - cMenTreeConnectWithOptions.Enabled = false; - cMenTreeDisconnect.Enabled = false; - cMenTreeToolsTransferFile.Enabled = false; - cMenTreeConnectWithOptions.Enabled = false; - cMenTreeToolsSort.Enabled = false; - cMenTreeToolsExternalApps.Enabled = false; - cMenTreeDuplicate.Enabled = false; - cMenTreeRename.Enabled = true; - cMenTreeDelete.Enabled = false; - cMenTreeMoveUp.Enabled = false; - cMenTreeMoveDown.Enabled = false; - } - else - { - cMenTree.Enabled = false; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("ShowHideTreeContextMenuItems (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - #endregion - #region Drag and Drop - private static void tvConnections_DragDrop(object sender, DragEventArgs e) - { - try - { - //Check that there is a TreeNode being dragged - if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", true) == false) - return; + private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + var senderAsContainerInfo = sender as ContainerInfo; + switch (args?.Action) + { + case NotifyCollectionChangedAction.Add: + var childList = senderAsContainerInfo?.Children; + ConnectionInfo otherChild = null; + if (childList?.Count > 1) + try { otherChild = childList.First(child => !args.NewItems.Contains(child)); } catch { } + RefreshTreeObject(otherChild ?? senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Remove: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Move: + RefreshTreeObjects(args.OldItems); + break; + case NotifyCollectionChangedAction.Reset: + RefreshTreeObject(senderAsContainerInfo); + break; + case NotifyCollectionChangedAction.Replace: + break; + case null: + break; + } + } - TreeView treeviewThatSentTheEvent = (TreeView)sender; - TreeNode nodeBeingDragged = (TreeNode)(e.Data.GetData("System.Windows.Forms.TreeNode")); - TreeNode nodeBeingTargetedByDragOverEvent = treeviewThatSentTheEvent.SelectedNode; + private void RefreshTreeObject(ConnectionInfo modelObject) + { + olvConnections.RefreshObject(modelObject); + } - TreeNodeMover treeNodeMover = new TreeNodeMover(nodeBeingDragged); - treeNodeMover.MoveNode(nodeBeingTargetedByDragOverEvent); + private void RefreshTreeObjects(IList modelObjects) + { + try + { + olvConnections.RefreshObjects(modelObjects); } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_DragDrop (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - - - private static void tvConnections_DragEnter(object sender, DragEventArgs e) - { - try - { - //See if there is a TreeNode being dragged - if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", true)) - { - //TreeNode found allow move effect - e.Effect = DragDropEffects.Move; - } - else - { - //No TreeNode found, prevent move - e.Effect = DragDropEffects.None; - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_DragEnter (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private static void tvConnections_DragOver(object sender, DragEventArgs e) - { - try - { - //Check that there is a TreeNode being dragged - if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", true) == false) - { - return; - } - - //Get the TreeView raising the event (in case multiple on form) - TreeView selectedTreeview = (TreeView) sender; - - //As the mouse moves over nodes, provide feedback to - //the user by highlighting the node that is the - //current drop target - Point pt = ((TreeView) sender).PointToClient(new Point(e.X, e.Y)); - TreeNode targetNode = selectedTreeview.GetNodeAt(pt); - - //Select the node currently under the cursor - selectedTreeview.SelectedNode = targetNode; - - //Check that the selected node is not the dropNode and - //also that it is not a child of the dropNode and - //therefore an invalid target - TreeNode dropNode = (TreeNode) (e.Data.GetData("System.Windows.Forms.TreeNode")); - - while (targetNode != null) - { - var puttyRootInfo = targetNode.Tag as Root.PuttySessions.PuttySessionsNodeInfo; - if (puttyRootInfo != null || targetNode == dropNode) - { - e.Effect = DragDropEffects.None; - return ; - } - targetNode = targetNode.Parent; - } - - //Currently selected node is a suitable target - e.Effect = DragDropEffects.Move; - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_DragOver (UI.Window.ConnectionTreeWindow) failed", ex); - } - } - - private void tvConnections_ItemDrag(object sender, ItemDragEventArgs e) - { - try - { - TreeNode dragTreeNode = e.Item as TreeNode; - - if (dragTreeNode?.Tag == null) - { - return; - } - if (dragTreeNode.Tag is PuttySessionInfo|| !(dragTreeNode.Tag is ConnectionInfo|| dragTreeNode.Tag is ContainerInfo)) - { - tvConnections.SelectedNode = dragTreeNode; - return; - } - - //Set the drag node and initiate the DragDrop - DoDragDrop(e.Item, DragDropEffects.Move); - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_ItemDrag (UI.Window.ConnectionTreeWindow) failed", ex); - } - } + catch (Exception) + { + } + } #endregion #region Tree Context Menu private void cMenTreeAddConnection_Click(object sender, EventArgs e) { AddConnection(); - Runtime.SaveConnectionsBG(); + Runtime.SaveConnectionsAsync(); } private void cMenTreeAddFolder_Click(object sender, EventArgs e) { AddFolder(); - Runtime.SaveConnectionsBG(); + Runtime.SaveConnectionsAsync(); } - private static void cMenTreeConnect_Click(object sender, EventArgs e) + private void SortNodesRecursive(ConnectionInfo sortTarget, ListSortDirection sortDirection) + { + if (sortTarget == null) + sortTarget = GetRootConnectionNode(); + + var sortTargetAsContainer = sortTarget as ContainerInfo; + if (sortTargetAsContainer != null) + sortTargetAsContainer.SortRecursive(sortDirection); + else + SelectedNode.Parent.SortRecursive(sortDirection); + + Runtime.SaveConnectionsAsync(); + } + + private void cMenTreeMoveUp_Click(object sender, EventArgs e) { - Runtime.OpenConnection(ConnectionInfo.Force.DoNotJump); + SelectedNode.Parent.PromoteChild(SelectedNode); + Runtime.SaveConnectionsAsync(); } - private static void cMenTreeConnectWithOptionsConnectToConsoleSession_Click(object sender, EventArgs e) + private void cMenTreeMoveDown_Click(object sender, EventArgs e) { - Runtime.OpenConnection(ConnectionInfo.Force.UseConsoleSession | ConnectionInfo.Force.DoNotJump); - } - - private static void cMenTreeConnectWithOptionsNoCredentials_Click(object sender, EventArgs e) - { - Runtime.OpenConnection(ConnectionInfo.Force.NoCredentials); - } - - private static void cMenTreeConnectWithOptionsDontConnectToConsoleSession_Click(object sender, EventArgs e) - { - Runtime.OpenConnection(ConnectionInfo.Force.DontUseConsoleSession | ConnectionInfo.Force.DoNotJump); - } - - private static void cMenTreeConnectWithOptionsConnectInFullscreen_Click(object sender, EventArgs e) - { - Runtime.OpenConnection(ConnectionInfo.Force.Fullscreen | ConnectionInfo.Force.DoNotJump); - } - - private static void cMenTreeConnectWithOptionsChoosePanelBeforeConnecting_Click(object sender, EventArgs e) - { - Runtime.OpenConnection(ConnectionInfo.Force.OverridePanel | ConnectionInfo.Force.DoNotJump); - } - - private void cMenTreeDisconnect_Click(object sender, EventArgs e) - { - DisconnectConnection(); - } - - private static void cMenTreeToolsTransferFile_Click(object sender, EventArgs e) - { - SshTransferFile(); - } - - private void mMenSortAscending_Click(object sender, EventArgs e) - { - tvConnections.BeginUpdate(); - ConnectionTree.Sort(tvConnections.Nodes[0], SortOrder.Ascending); - tvConnections.EndUpdate(); - Runtime.SaveConnectionsBG(); - } - - private void cMenTreeToolsSortAscending_Click(object sender, EventArgs e) - { - tvConnections.BeginUpdate(); - ConnectionTree.Sort(tvConnections.SelectedNode, SortOrder.Ascending); - tvConnections.EndUpdate(); - Runtime.SaveConnectionsBG(); - } - - private void cMenTreeToolsSortDescending_Click(object sender, EventArgs e) - { - tvConnections.BeginUpdate(); - ConnectionTree.Sort(tvConnections.SelectedNode, SortOrder.Descending); - tvConnections.EndUpdate(); - Runtime.SaveConnectionsBG(); - } - - private void cMenTree_DropDownOpening(object sender, EventArgs e) - { - AddExternalApps(); - } - - private static void cMenTreeToolsExternalAppsEntry_Click(object sender, EventArgs e) - { - StartExternalApp((Tools.ExternalTool)((ToolStripMenuItem)sender).Tag); - } - - private void cMenTreeDuplicate_Click(object sender, EventArgs e) - { - ConnectionTreeNode.CloneNode(tvConnections.SelectedNode); - Runtime.SaveConnectionsBG(); - } - - private static void cMenTreeRename_Click(object sender, EventArgs e) - { - ConnectionTree.StartRenameSelectedNode(); - Runtime.SaveConnectionsBG(); - } - - private static void cMenTreeDelete_Click(object sender, EventArgs e) - { - ConnectionTree.DeleteSelectedNode(); - Runtime.SaveConnectionsBG(); - } - - private static void cMenTreeImportFile_Click(object sender, EventArgs e) - { - Import.ImportFromFile(Windows.treeForm.tvConnections.Nodes[0], Windows.treeForm.tvConnections.SelectedNode, true); - } - - private static void cMenTreeImportActiveDirectory_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.ActiveDirectoryImport); - } - - private static void cMenTreeImportPortScan_Click(object sender, EventArgs e) - { - Windows.Show(WindowType.PortScan); - } - - private static void cMenTreeExportFile_Click(object sender, EventArgs e) - { - Export.ExportToFile(Windows.treeForm.tvConnections.Nodes[0], Windows.treeForm.tvConnections.SelectedNode); - } - private static void cMenTreeMoveUp_Click(object sender, EventArgs e) - { - ConnectionTree.MoveNodeUp(); - Runtime.SaveConnectionsBG(); - } - - private static void cMenTreeMoveDown_Click(object sender, EventArgs e) - { - ConnectionTree.MoveNodeDown(); - Runtime.SaveConnectionsBG(); + SelectedNode.Parent.DemoteChild(SelectedNode); + Runtime.SaveConnectionsAsync(); } #endregion - + #region Context Menu Actions - public void AddConnection() + public void AddConnection() { try { - if (tvConnections.SelectedNode == null) - { - tvConnections.SelectedNode = tvConnections.Nodes[0]; - } - - TreeNode newTreeNode = ConnectionTreeNode.AddNode(TreeNodeType.Connection); - if (newTreeNode == null) - { - Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "UI.Window.Tree.AddConnection() failed." + Environment.NewLine + "mRemoteNG.Tree.Node.AddNode() returned Nothing.", true); - return ; - } - - TreeNode containerNode = tvConnections.SelectedNode; - if (ConnectionTreeNode.GetNodeType(containerNode) == TreeNodeType.Connection) - { - containerNode = containerNode.Parent; - } - - ConnectionInfo newConnectionInfo = new ConnectionInfo(); - newConnectionInfo.CopyFrom(DefaultConnectionInfo.Instance); - if (ConnectionTreeNode.GetNodeType(containerNode) == TreeNodeType.Root) - { - newConnectionInfo.Inheritance.DisableInheritance(); - } - else - { - newConnectionInfo.Parent = (ContainerInfo)containerNode.Tag; - } - - newConnectionInfo.TreeNode = newTreeNode; - newTreeNode.Tag = newConnectionInfo; - Runtime.ConnectionList.Add(newConnectionInfo); - - containerNode.Nodes.Add(newTreeNode); - - tvConnections.SelectedNode = newTreeNode; - tvConnections.SelectedNode.BeginEdit(); - } + AddNode(new ConnectionInfo()); + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("UI.Window.Tree.AddConnection() failed.", ex); } } - - public void AddFolder() + + public void AddFolder() { try { - TreeNode newNode = ConnectionTreeNode.AddNode(TreeNodeType.Container); - ContainerInfo newContainerInfo = new ContainerInfo(); - newContainerInfo.CopyFrom(DefaultConnectionInfo.Instance); - newNode.Tag = newContainerInfo; - newContainerInfo.TreeNode = newNode; - - TreeNode selectedNode = ConnectionTree.SelectedNode; - TreeNode parentNode; - if (selectedNode == null) - { - parentNode = tvConnections.Nodes[0]; - } - else - { - if (ConnectionTreeNode.GetNodeType(selectedNode) == TreeNodeType.Connection) - parentNode = selectedNode.Parent; - else - parentNode = selectedNode; - } - - newContainerInfo.Name = newNode.Text; - - // We can only inherit from a container node, not the root node or connection nodes - if (ConnectionTreeNode.GetNodeType(parentNode) == TreeNodeType.Container) - { - newContainerInfo.Parent = (ContainerInfo)parentNode.Tag; - } - else - { - newContainerInfo.Inheritance.DisableInheritance(); - } - - Runtime.ContainerList.Add(newContainerInfo); - parentNode.Nodes.Add(newNode); - - tvConnections.SelectedNode = newNode; - tvConnections.SelectedNode.BeginEdit(); - } + AddNode(new ContainerInfo()); + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace(Language.strErrorAddFolderFailed, ex); } } - - private void DisconnectConnection() + + private void AddNode(ConnectionInfo newNode) + { + if (SelectedNode == null) return; + DefaultConnectionInfo.Instance.SaveTo(newNode); + DefaultConnectionInheritance.Instance.SaveTo(newNode.Inheritance); + var selectedContainer = SelectedNode as ContainerInfo; + var parent = selectedContainer ?? SelectedNode?.Parent; + newNode.SetParent(parent); + olvConnections.Expand(parent); + olvConnections.SelectObject(newNode); + olvConnections.EnsureModelVisible(newNode); + } + + private void DisconnectConnection(ConnectionInfo connectionInfo) { try { - if (tvConnections.SelectedNode != null) - { - if (tvConnections.SelectedNode.Tag is ConnectionInfo) - { - ConnectionInfo conI = (ConnectionInfo)tvConnections.SelectedNode.Tag; - for (int i = 0; i <= conI.OpenConnections.Count - 1; i++) - { - conI.OpenConnections[i].Disconnect(); - } - } - - if (tvConnections.SelectedNode.Tag is ContainerInfo) - { - foreach (TreeNode n in tvConnections.SelectedNode.Nodes) - { - if (n.Tag is ConnectionInfo) - { - ConnectionInfo conI = (ConnectionInfo)n.Tag; - for (int i = 0; i <= conI.OpenConnections.Count - 1; i++) - { - conI.OpenConnections[i].Disconnect(); - } - } - } - } - } + if (connectionInfo == null) return; + var nodeAsContainer = connectionInfo as ContainerInfo; + if (nodeAsContainer != null) + { + foreach (var child in nodeAsContainer.Children) + { + for (var i = 0; i <= child.OpenConnections.Count - 1; i++) + { + child.OpenConnections[i].Disconnect(); + } + } + } + else + { + for (var i = 0; i <= connectionInfo.OpenConnections.Count - 1; i++) + { + connectionInfo.OpenConnections[i].Disconnect(); + } + } } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("DisconnectConnection (UI.Window.ConnectionTreeWindow) failed", ex); } } - - private static void SshTransferFile() + + private void SshTransferFile() { try { - Windows.Show(WindowType.SSHTransfer); - - ConnectionInfo conI = (ConnectionInfo)ConnectionTree.SelectedNode.Tag; - - Windows.sshtransferForm.Hostname = conI.Hostname; - Windows.sshtransferForm.Username = conI.Username; - Windows.sshtransferForm.Password = conI.Password; - Windows.sshtransferForm.Port = Convert.ToString(conI.Port); + Windows.Show(WindowType.SSHTransfer); + Windows.SshtransferForm.Hostname = SelectedNode.Hostname; + Windows.SshtransferForm.Username = SelectedNode.Username; + Windows.SshtransferForm.Password = SelectedNode.Password; + Windows.SshtransferForm.Port = Convert.ToString(SelectedNode.Port); } catch (Exception ex) { Runtime.MessageCollector.AddExceptionStackTrace("SSHTransferFile (UI.Window.ConnectionTreeWindow) failed", ex); } } - - private void AddExternalApps() - { - try - { - //clean up - //since new items are added below, we have to dispose of any previous items first - if (cMenTreeToolsExternalApps.DropDownItems.Count > 0) - { - for (int i = cMenTreeToolsExternalApps.DropDownItems.Count - 1; i >= 0; i--) - cMenTreeToolsExternalApps.DropDownItems[i].Dispose(); - cMenTreeToolsExternalApps.DropDownItems.Clear(); - } - - //add ext apps - foreach (Tools.ExternalTool extA in Runtime.ExternalTools) - { - ToolStripMenuItem nItem = new ToolStripMenuItem(); - nItem.Text = extA.DisplayName; - nItem.Tag = extA; - - nItem.Image = extA.Image; - - nItem.Click += cMenTreeToolsExternalAppsEntry_Click; - - cMenTreeToolsExternalApps.DropDownItems.Add(nItem); - } - } - catch (Exception ex) - { - Runtime.MessageCollector.AddExceptionStackTrace("cMenTreeTools_DropDownOpening failed (UI.Window.ConnectionTreeWindow)", ex); - } - } - - private static void StartExternalApp(Tools.ExternalTool externalTool) + private void StartExternalApp(ExternalTool externalTool) { try { - if (ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.Connection | ConnectionTreeNode.GetNodeType(ConnectionTree.SelectedNode) == TreeNodeType.PuttySession) - { - externalTool.Start((ConnectionInfo)ConnectionTree.SelectedNode.Tag); - } + if (SelectedNode.GetTreeNodeType() == TreeNodeType.Connection | SelectedNode.GetTreeNodeType() == TreeNodeType.PuttySession) + externalTool.Start(SelectedNode); } catch (Exception ex) { @@ -838,42 +644,19 @@ namespace mRemoteNG.UI.Window } #endregion - #region Menu - private void mMenViewExpandAllFolders_Click(object sender, EventArgs e) - { - ConnectionTree.ExpandAllNodes(); - } - - private void mMenViewCollapseAllFolders_Click(object sender, EventArgs e) - { - if (tvConnections.SelectedNode != null) - { - if (tvConnections.SelectedNode.IsEditing) - { - tvConnections.SelectedNode.EndEdit(false); - } - } - ConnectionTree.CollapseAllNodes(); - } - #endregion - #region Search private void txtSearch_GotFocus(object sender, EventArgs e) { txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextColor; if (txtSearch.Text == Language.strSearchPrompt) - { txtSearch.Text = ""; - } } private void txtSearch_LostFocus(object sender, EventArgs e) { - if (txtSearch.Text == "") - { - txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; - txtSearch.Text = Language.strSearchPrompt; - } + if (txtSearch.Text != "") return; + txtSearch.ForeColor = Themes.ThemeManager.ActiveTheme.SearchBoxTextPromptColor; + txtSearch.Text = Language.strSearchPrompt; } private void txtSearch_KeyDown(object sender, KeyEventArgs e) @@ -883,15 +666,19 @@ namespace mRemoteNG.UI.Window if (e.KeyCode == Keys.Escape) { e.Handled = true; - tvConnections.Focus(); + olvConnections.Focus(); } else if (e.KeyCode == Keys.Up) { - tvConnections.SelectedNode = tvConnections.SelectedNode.PrevVisibleNode; + var match = _nodeSearcher.PreviousMatch(); + JumpToNode(match); + e.Handled = true; } else if (e.KeyCode == Keys.Down) { - tvConnections.SelectedNode = tvConnections.SelectedNode.NextVisibleNode; + var match = _nodeSearcher.NextMatch(); + JumpToNode(match); + e.Handled = true; } else { @@ -906,20 +693,38 @@ namespace mRemoteNG.UI.Window private void txtSearch_TextChanged(object sender, EventArgs e) { - tvConnections.SelectedNode = ConnectionTree.Find(tvConnections.Nodes[0], txtSearch.Text); - } + if (txtSearch.Text == "") return; + _nodeSearcher?.SearchByName(txtSearch.Text); + JumpToNode(_nodeSearcher?.CurrentMatch); + } + + private void JumpToNode(ConnectionInfo connectionInfo) + { + if (connectionInfo == null) + { + olvConnections.SelectedObject = null; + return; + } + ExpandParentsRecursive(connectionInfo); + olvConnections.SelectObject(connectionInfo); + olvConnections.EnsureModelVisible(connectionInfo); + } + + private void ExpandParentsRecursive(ConnectionInfo connectionInfo) + { + if (connectionInfo?.Parent == null) return; + olvConnections.Expand(connectionInfo.Parent); + ExpandParentsRecursive(connectionInfo.Parent); + } private void tvConnections_KeyPress(object sender, KeyPressEventArgs e) { try { - if (char.IsLetterOrDigit(e.KeyChar)) - { - txtSearch.Text = e.KeyChar.ToString(); - - txtSearch.Focus(); - txtSearch.SelectionStart = txtSearch.TextLength; - } + if (!char.IsLetterOrDigit(e.KeyChar)) return; + txtSearch.Text = e.KeyChar.ToString(); + txtSearch.Focus(); + txtSearch.SelectionStart = txtSearch.TextLength; } catch (Exception ex) { @@ -933,27 +738,14 @@ namespace mRemoteNG.UI.Window { if (e.KeyCode == Keys.Enter) { - if (tvConnections.SelectedNode.Tag is ConnectionInfo) - { - e.Handled = true; - Runtime.OpenConnection(); - } - else - { - if (tvConnections.SelectedNode.IsExpanded) - { - tvConnections.SelectedNode.Collapse(true); - } - else - { - tvConnections.SelectedNode.Expand(); - } - } + e.Handled = true; + ConnectionInitiator.OpenConnection(SelectedNode); } - else if (e.KeyCode == Keys.Escape ^ e.KeyCode == Keys.Control | e.KeyCode == Keys.F) + else if (e.Control && e.KeyCode == Keys.F) { txtSearch.Focus(); - txtSearch.SelectionStart = txtSearch.TextLength; + txtSearch.SelectAll(); + e.Handled = true; } } catch (Exception ex) diff --git a/mRemoteV1/UI/Window/ConnectionTreeWindow.resx b/mRemoteV1/UI/Window/ConnectionTreeWindow.resx index 4c0f58aeb..dfeabba7a 100644 --- a/mRemoteV1/UI/Window/ConnectionTreeWindow.resx +++ b/mRemoteV1/UI/Window/ConnectionTreeWindow.resx @@ -112,18 +112,15 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 208, 19 - - + 17, 17 - + 119, 19 \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs b/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs new file mode 100644 index 000000000..08a0ef4ab --- /dev/null +++ b/mRemoteV1/UI/Window/ConnectionWindow.Designer.cs @@ -0,0 +1,236 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using TabControl = Crownwood.Magic.Controls.TabControl; + + +namespace mRemoteNG.UI.Window +{ + public partial class ConnectionWindow + { + internal ContextMenuStrip cmenTab; + private System.ComponentModel.Container components; + private ToolStripMenuItem cmenTabFullscreen; + private ToolStripMenuItem cmenTabScreenshot; + private ToolStripMenuItem cmenTabTransferFile; + private ToolStripMenuItem cmenTabSendSpecialKeys; + private ToolStripSeparator cmenTabSep1; + private ToolStripMenuItem cmenTabRenameTab; + private ToolStripMenuItem cmenTabDuplicateTab; + private ToolStripMenuItem cmenTabDisconnect; + private ToolStripMenuItem cmenTabSmartSize; + private ToolStripMenuItem cmenTabSendSpecialKeysCtrlAltDel; + private ToolStripMenuItem cmenTabSendSpecialKeysCtrlEsc; + private ToolStripMenuItem cmenTabViewOnly; + internal ToolStripMenuItem cmenTabReconnect; + internal ToolStripMenuItem cmenTabExternalApps; + private ToolStripMenuItem cmenTabStartChat; + private ToolStripMenuItem cmenTabRefreshScreen; + private ToolStripSeparator ToolStripSeparator1; + private ToolStripMenuItem cmenTabPuttySettings; + + + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConnectionWindow)); + TabController = new TabControl(); + cmenTab = new ContextMenuStrip(components); + cmenTabFullscreen = new ToolStripMenuItem(); + cmenTabSmartSize = new ToolStripMenuItem(); + cmenTabViewOnly = new ToolStripMenuItem(); + ToolStripSeparator1 = new ToolStripSeparator(); + cmenTabScreenshot = new ToolStripMenuItem(); + cmenTabStartChat = new ToolStripMenuItem(); + cmenTabTransferFile = new ToolStripMenuItem(); + cmenTabRefreshScreen = new ToolStripMenuItem(); + cmenTabSendSpecialKeys = new ToolStripMenuItem(); + cmenTabSendSpecialKeysCtrlAltDel = new ToolStripMenuItem(); + cmenTabSendSpecialKeysCtrlEsc = new ToolStripMenuItem(); + cmenTabExternalApps = new ToolStripMenuItem(); + cmenTabSep1 = new ToolStripSeparator(); + cmenTabRenameTab = new ToolStripMenuItem(); + cmenTabDuplicateTab = new ToolStripMenuItem(); + cmenTabReconnect = new ToolStripMenuItem(); + cmenTabDisconnect = new ToolStripMenuItem(); + cmenTabPuttySettings = new ToolStripMenuItem(); + cmenTab.SuspendLayout(); + SuspendLayout(); + // + //TabController + // + TabController.Anchor = ((AnchorStyles.Top | AnchorStyles.Bottom) + | AnchorStyles.Left) + | AnchorStyles.Right; + TabController.Appearance = TabControl.VisualAppearance.MultiDocument; + TabController.Cursor = Cursors.Hand; + TabController.DragFromControl = false; + TabController.IDEPixelArea = true; + TabController.IDEPixelBorder = false; + TabController.Location = new Point(0, -1); + TabController.Name = "TabController"; + TabController.Size = new Size(632, 454); + TabController.TabIndex = 0; + // + //cmenTab + // + cmenTab.Items.AddRange(new ToolStripItem[] + { + cmenTabFullscreen, + cmenTabSmartSize, + cmenTabViewOnly, + ToolStripSeparator1, + cmenTabScreenshot, + cmenTabStartChat, + cmenTabTransferFile, + cmenTabRefreshScreen, + cmenTabSendSpecialKeys, + cmenTabPuttySettings, + cmenTabExternalApps, + cmenTabSep1, + cmenTabRenameTab, + cmenTabDuplicateTab, + cmenTabReconnect, + cmenTabDisconnect + }); + cmenTab.Name = "cmenTab"; + cmenTab.RenderMode = ToolStripRenderMode.Professional; + cmenTab.Size = new Size(202, 346); + // + //cmenTabFullscreen + // + cmenTabFullscreen.Image = Resources.arrow_out; + cmenTabFullscreen.Name = "cmenTabFullscreen"; + cmenTabFullscreen.Size = new Size(201, 22); + cmenTabFullscreen.Text = @"Fullscreen (RDP)"; + // + //cmenTabSmartSize + // + cmenTabSmartSize.Image = Resources.SmartSize; + cmenTabSmartSize.Name = "cmenTabSmartSize"; + cmenTabSmartSize.Size = new Size(201, 22); + cmenTabSmartSize.Text = @"SmartSize (RDP/VNC)"; + // + //cmenTabViewOnly + // + cmenTabViewOnly.Name = "cmenTabViewOnly"; + cmenTabViewOnly.Size = new Size(201, 22); + cmenTabViewOnly.Text = @"View Only (VNC)"; + // + //ToolStripSeparator1 + // + ToolStripSeparator1.Name = "ToolStripSeparator1"; + ToolStripSeparator1.Size = new Size(198, 6); + // + //cmenTabScreenshot + // + cmenTabScreenshot.Image = Resources.Screenshot_Add; + cmenTabScreenshot.Name = "cmenTabScreenshot"; + cmenTabScreenshot.Size = new Size(201, 22); + cmenTabScreenshot.Text = @"Screenshot"; + // + //cmenTabStartChat + // + cmenTabStartChat.Image = Resources.Chat; + cmenTabStartChat.Name = "cmenTabStartChat"; + cmenTabStartChat.Size = new Size(201, 22); + cmenTabStartChat.Text = @"Start Chat (VNC)"; + cmenTabStartChat.Visible = false; + // + //cmenTabTransferFile + // + cmenTabTransferFile.Image = Resources.SSHTransfer; + cmenTabTransferFile.Name = "cmenTabTransferFile"; + cmenTabTransferFile.Size = new Size(201, 22); + cmenTabTransferFile.Text = @"Transfer File (SSH)"; + // + //cmenTabRefreshScreen + // + cmenTabRefreshScreen.Image = Resources.Refresh; + cmenTabRefreshScreen.Name = "cmenTabRefreshScreen"; + cmenTabRefreshScreen.Size = new Size(201, 22); + cmenTabRefreshScreen.Text = @"Refresh Screen (VNC)"; + // + //cmenTabSendSpecialKeys + // + cmenTabSendSpecialKeys.DropDownItems.AddRange(new ToolStripItem[] + { + cmenTabSendSpecialKeysCtrlAltDel, + cmenTabSendSpecialKeysCtrlEsc + }); + cmenTabSendSpecialKeys.Image = Resources.Keyboard; + cmenTabSendSpecialKeys.Name = "cmenTabSendSpecialKeys"; + cmenTabSendSpecialKeys.Size = new Size(201, 22); + cmenTabSendSpecialKeys.Text = @"Send special Keys (VNC)"; + // + //cmenTabSendSpecialKeysCtrlAltDel + // + cmenTabSendSpecialKeysCtrlAltDel.Name = "cmenTabSendSpecialKeysCtrlAltDel"; + cmenTabSendSpecialKeysCtrlAltDel.Size = new Size(141, 22); + cmenTabSendSpecialKeysCtrlAltDel.Text = @"Ctrl+Alt+Del"; + // + //cmenTabSendSpecialKeysCtrlEsc + // + cmenTabSendSpecialKeysCtrlEsc.Name = "cmenTabSendSpecialKeysCtrlEsc"; + cmenTabSendSpecialKeysCtrlEsc.Size = new Size(141, 22); + cmenTabSendSpecialKeysCtrlEsc.Text = @"Ctrl+Esc"; + // + //cmenTabExternalApps + // + cmenTabExternalApps.Image = (Image)(resources.GetObject("cmenTabExternalApps.Image")); + cmenTabExternalApps.Name = "cmenTabExternalApps"; + cmenTabExternalApps.Size = new Size(201, 22); + cmenTabExternalApps.Text = @"External Applications"; + // + //cmenTabSep1 + // + cmenTabSep1.Name = "cmenTabSep1"; + cmenTabSep1.Size = new Size(198, 6); + // + //cmenTabRenameTab + // + cmenTabRenameTab.Image = Resources.Rename; + cmenTabRenameTab.Name = "cmenTabRenameTab"; + cmenTabRenameTab.Size = new Size(201, 22); + cmenTabRenameTab.Text = @"Rename Tab"; + // + //cmenTabDuplicateTab + // + cmenTabDuplicateTab.Name = "cmenTabDuplicateTab"; + cmenTabDuplicateTab.Size = new Size(201, 22); + cmenTabDuplicateTab.Text = @"Duplicate Tab"; + // + //cmenTabReconnect + // + cmenTabReconnect.Image = (Image)(resources.GetObject("cmenTabReconnect.Image")); + cmenTabReconnect.Name = "cmenTabReconnect"; + cmenTabReconnect.Size = new Size(201, 22); + cmenTabReconnect.Text = @"Reconnect"; + // + //cmenTabDisconnect + // + cmenTabDisconnect.Image = Resources.Pause; + cmenTabDisconnect.Name = "cmenTabDisconnect"; + cmenTabDisconnect.Size = new Size(201, 22); + cmenTabDisconnect.Text = @"Disconnect"; + // + //cmenTabPuttySettings + // + cmenTabPuttySettings.Name = "cmenTabPuttySettings"; + cmenTabPuttySettings.Size = new Size(201, 22); + cmenTabPuttySettings.Text = @"PuTTY Settings"; + // + //Connection + // + ClientSize = new Size(632, 453); + Controls.Add(TabController); + Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point, Convert.ToByte(0)); + Icon = Resources.mRemote_Icon; + Name = "Connection"; + TabText = @"UI.Window.Connection"; + Text = @"UI.Window.Connection"; + cmenTab.ResumeLayout(false); + ResumeLayout(false); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ConnectionWindow.cs b/mRemoteV1/UI/Window/ConnectionWindow.cs index 756469363..908fab04e 100644 --- a/mRemoteV1/UI/Window/ConnectionWindow.cs +++ b/mRemoteV1/UI/Window/ConnectionWindow.cs @@ -1,6 +1,9 @@ using System; using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; using System.Windows.Forms; +using BrightIdeasSoftware; using mRemoteNG.Connection; using mRemoteNG.App; using WeifenLuo.WinFormsUI.Docking; @@ -11,47 +14,58 @@ using mRemoteNG.Connection.Protocol; using mRemoteNG.UI.Forms; using mRemoteNG.UI.TaskDialog; using mRemoteNG.App.Info; +using mRemoteNG.Container; +using mRemoteNG.Messages; +using mRemoteNG.Tools; using mRemoteNG.UI.Forms.Input; +using Message = System.Windows.Forms.Message; +using TabControl = Crownwood.Magic.Controls.TabControl; +using TabPage = Crownwood.Magic.Controls.TabPage; + namespace mRemoteNG.UI.Window { - public class ConnectionWindow : BaseWindow + public partial class ConnectionWindow : BaseWindow { - #region Form Init - internal ContextMenuStrip cmenTab; - private System.ComponentModel.Container components; - private ToolStripMenuItem cmenTabFullscreen; - private ToolStripMenuItem cmenTabScreenshot; - private ToolStripMenuItem cmenTabTransferFile; - private ToolStripMenuItem cmenTabSendSpecialKeys; - private ToolStripSeparator cmenTabSep1; - private ToolStripMenuItem cmenTabRenameTab; - private ToolStripMenuItem cmenTabDuplicateTab; - private ToolStripMenuItem cmenTabDisconnect; - private ToolStripMenuItem cmenTabSmartSize; - private ToolStripMenuItem cmenTabSendSpecialKeysCtrlAltDel; - private ToolStripMenuItem cmenTabSendSpecialKeysCtrlEsc; - private ToolStripMenuItem cmenTabViewOnly; - internal ToolStripMenuItem cmenTabReconnect; - internal ToolStripMenuItem cmenTabExternalApps; - private ToolStripMenuItem cmenTabStartChat; - private ToolStripMenuItem cmenTabRefreshScreen; - private ToolStripSeparator ToolStripSeparator1; - private ToolStripMenuItem cmenTabPuttySettings; + public TabControl TabController; + - public Crownwood.Magic.Controls.TabControl TabController; - private void InitializeComponent() + #region Public Methods + public ConnectionWindow(DockContent panel, string formText = "") + { + if (formText == "") + { + formText = Language.strNewPanel; + } + + WindowType = WindowType.Connection; + DockPnl = panel; + InitializeComponent(); + SetEventHandlers(); + // ReSharper disable once VirtualMemberCallInConstructor + Text = formText; + TabText = formText; + } + + private void SetEventHandlers() + { + SetFormEventHandlers(); + SetTabControllerEventHandlers(); + SetContextMenuEventHandlers(); + } + + private void SetFormEventHandlers() { - components = new System.ComponentModel.Container(); Load += Connection_Load; DockStateChanged += Connection_DockStateChanged; FormClosing += Connection_FormClosing; - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConnectionWindow)); - TabController = new Crownwood.Magic.Controls.TabControl(); + } + + private void SetTabControllerEventHandlers() + { TabController.ClosePressed += TabController_ClosePressed; TabController.DoubleClickTab += TabController_DoubleClickTab; TabController.DragDrop += TabController_DragDrop; - TabController.DragEnter += TabController_DragEnter; TabController.DragOver += TabController_DragOver; TabController.SelectionChanged += TabController_SelectionChanged; TabController.MouseUp += TabController_MouseUp; @@ -60,249 +74,53 @@ namespace mRemoteNG.UI.Window TabController.PageDragMove += TabController_PageDragMove; TabController.PageDragEnd += TabController_PageDragEnd; TabController.PageDragQuit += TabController_PageDragEnd; - cmenTab = new ContextMenuStrip(components); - cmenTabFullscreen = new ToolStripMenuItem(); - cmenTabFullscreen.Click += cmenTabFullscreen_Click; - cmenTabSmartSize = new ToolStripMenuItem(); - cmenTabSmartSize.Click += cmenTabSmartSize_Click; - cmenTabViewOnly = new ToolStripMenuItem(); - cmenTabViewOnly.Click += cmenTabViewOnly_Click; - ToolStripSeparator1 = new ToolStripSeparator(); - cmenTabScreenshot = new ToolStripMenuItem(); - cmenTabScreenshot.Click += cmenTabScreenshot_Click; - cmenTabStartChat = new ToolStripMenuItem(); - cmenTabStartChat.Click += cmenTabStartChat_Click; - cmenTabTransferFile = new ToolStripMenuItem(); - cmenTabTransferFile.Click += cmenTabTransferFile_Click; - cmenTabRefreshScreen = new ToolStripMenuItem(); - cmenTabRefreshScreen.Click += cmenTabRefreshScreen_Click; - cmenTabSendSpecialKeys = new ToolStripMenuItem(); - cmenTabSendSpecialKeysCtrlAltDel = new ToolStripMenuItem(); - cmenTabSendSpecialKeysCtrlAltDel.Click += cmenTabSendSpecialKeysCtrlAltDel_Click; - cmenTabSendSpecialKeysCtrlEsc = new ToolStripMenuItem(); - cmenTabSendSpecialKeysCtrlEsc.Click += cmenTabSendSpecialKeysCtrlEsc_Click; - cmenTabExternalApps = new ToolStripMenuItem(); - cmenTabSep1 = new ToolStripSeparator(); - cmenTabRenameTab = new ToolStripMenuItem(); - cmenTabRenameTab.Click += cmenTabRenameTab_Click; - cmenTabDuplicateTab = new ToolStripMenuItem(); - cmenTabDuplicateTab.Click += cmenTabDuplicateTab_Click; - cmenTabReconnect = new ToolStripMenuItem(); - cmenTabReconnect.Click += cmenTabReconnect_Click; - cmenTabDisconnect = new ToolStripMenuItem(); - cmenTabDisconnect.Click += cmenTabDisconnect_Click; - cmenTabPuttySettings = new ToolStripMenuItem(); - cmenTabPuttySettings.Click += cmenTabPuttySettings_Click; - cmenTab.SuspendLayout(); - SuspendLayout(); - // - //TabController - // - TabController.Anchor = ((AnchorStyles.Top | AnchorStyles.Bottom) - | AnchorStyles.Left) - | AnchorStyles.Right; - TabController.Appearance = Crownwood.Magic.Controls.TabControl.VisualAppearance.MultiDocument; - TabController.Cursor = Cursors.Hand; - TabController.DragFromControl = false; - TabController.IDEPixelArea = true; - TabController.IDEPixelBorder = false; - TabController.Location = new Point(0, -1); - TabController.Name = "TabController"; - TabController.Size = new Size(632, 454); - TabController.TabIndex = 0; - // - //cmenTab - // - cmenTab.Items.AddRange(new ToolStripItem[] { cmenTabFullscreen, cmenTabSmartSize, cmenTabViewOnly, ToolStripSeparator1, cmenTabScreenshot, cmenTabStartChat, cmenTabTransferFile, cmenTabRefreshScreen, cmenTabSendSpecialKeys, cmenTabPuttySettings, cmenTabExternalApps, cmenTabSep1, cmenTabRenameTab, cmenTabDuplicateTab, cmenTabReconnect, cmenTabDisconnect }); - cmenTab.Name = "cmenTab"; - cmenTab.RenderMode = ToolStripRenderMode.Professional; - cmenTab.Size = new Size(202, 346); - // - //cmenTabFullscreen - // - cmenTabFullscreen.Image = Resources.arrow_out; - cmenTabFullscreen.Name = "cmenTabFullscreen"; - cmenTabFullscreen.Size = new Size(201, 22); - cmenTabFullscreen.Text = @"Fullscreen (RDP)"; - // - //cmenTabSmartSize - // - cmenTabSmartSize.Image = Resources.SmartSize; - cmenTabSmartSize.Name = "cmenTabSmartSize"; - cmenTabSmartSize.Size = new Size(201, 22); - cmenTabSmartSize.Text = @"SmartSize (RDP/VNC)"; - // - //cmenTabViewOnly - // - cmenTabViewOnly.Name = "cmenTabViewOnly"; - cmenTabViewOnly.Size = new Size(201, 22); - cmenTabViewOnly.Text = @"View Only (VNC)"; - // - //ToolStripSeparator1 - // - ToolStripSeparator1.Name = "ToolStripSeparator1"; - ToolStripSeparator1.Size = new Size(198, 6); - // - //cmenTabScreenshot - // - cmenTabScreenshot.Image = Resources.Screenshot_Add; - cmenTabScreenshot.Name = "cmenTabScreenshot"; - cmenTabScreenshot.Size = new Size(201, 22); - cmenTabScreenshot.Text = @"Screenshot"; - // - //cmenTabStartChat - // - cmenTabStartChat.Image = Resources.Chat; - cmenTabStartChat.Name = "cmenTabStartChat"; - cmenTabStartChat.Size = new Size(201, 22); - cmenTabStartChat.Text = @"Start Chat (VNC)"; - cmenTabStartChat.Visible = false; - // - //cmenTabTransferFile - // - cmenTabTransferFile.Image = Resources.SSHTransfer; - cmenTabTransferFile.Name = "cmenTabTransferFile"; - cmenTabTransferFile.Size = new Size(201, 22); - cmenTabTransferFile.Text = @"Transfer File (SSH)"; - // - //cmenTabRefreshScreen - // - cmenTabRefreshScreen.Image = Resources.Refresh; - cmenTabRefreshScreen.Name = "cmenTabRefreshScreen"; - cmenTabRefreshScreen.Size = new Size(201, 22); - cmenTabRefreshScreen.Text = @"Refresh Screen (VNC)"; - // - //cmenTabSendSpecialKeys - // - cmenTabSendSpecialKeys.DropDownItems.AddRange(new ToolStripItem[] { cmenTabSendSpecialKeysCtrlAltDel, cmenTabSendSpecialKeysCtrlEsc }); - cmenTabSendSpecialKeys.Image = Resources.Keyboard; - cmenTabSendSpecialKeys.Name = "cmenTabSendSpecialKeys"; - cmenTabSendSpecialKeys.Size = new Size(201, 22); - cmenTabSendSpecialKeys.Text = @"Send special Keys (VNC)"; - // - //cmenTabSendSpecialKeysCtrlAltDel - // - cmenTabSendSpecialKeysCtrlAltDel.Name = "cmenTabSendSpecialKeysCtrlAltDel"; - cmenTabSendSpecialKeysCtrlAltDel.Size = new Size(141, 22); - cmenTabSendSpecialKeysCtrlAltDel.Text = @"Ctrl+Alt+Del"; - // - //cmenTabSendSpecialKeysCtrlEsc - // - cmenTabSendSpecialKeysCtrlEsc.Name = "cmenTabSendSpecialKeysCtrlEsc"; - cmenTabSendSpecialKeysCtrlEsc.Size = new Size(141, 22); - cmenTabSendSpecialKeysCtrlEsc.Text = @"Ctrl+Esc"; - // - //cmenTabExternalApps - // - cmenTabExternalApps.Image = (Image)(resources.GetObject("cmenTabExternalApps.Image")); - cmenTabExternalApps.Name = "cmenTabExternalApps"; - cmenTabExternalApps.Size = new Size(201, 22); - cmenTabExternalApps.Text = @"External Applications"; - // - //cmenTabSep1 - // - cmenTabSep1.Name = "cmenTabSep1"; - cmenTabSep1.Size = new Size(198, 6); - // - //cmenTabRenameTab - // - cmenTabRenameTab.Image = Resources.Rename; - cmenTabRenameTab.Name = "cmenTabRenameTab"; - cmenTabRenameTab.Size = new Size(201, 22); - cmenTabRenameTab.Text = @"Rename Tab"; - // - //cmenTabDuplicateTab - // - cmenTabDuplicateTab.Name = "cmenTabDuplicateTab"; - cmenTabDuplicateTab.Size = new Size(201, 22); - cmenTabDuplicateTab.Text = @"Duplicate Tab"; - // - //cmenTabReconnect - // - cmenTabReconnect.Image = (Image)(resources.GetObject("cmenTabReconnect.Image")); - cmenTabReconnect.Name = "cmenTabReconnect"; - cmenTabReconnect.Size = new Size(201, 22); - cmenTabReconnect.Text = @"Reconnect"; - // - //cmenTabDisconnect - // - cmenTabDisconnect.Image = Resources.Pause; - cmenTabDisconnect.Name = "cmenTabDisconnect"; - cmenTabDisconnect.Size = new Size(201, 22); - cmenTabDisconnect.Text = @"Disconnect"; - // - //cmenTabPuttySettings - // - cmenTabPuttySettings.Name = "cmenTabPuttySettings"; - cmenTabPuttySettings.Size = new Size(201, 22); - cmenTabPuttySettings.Text = @"PuTTY Settings"; - // - //Connection - // - ClientSize = new Size(632, 453); - Controls.Add(TabController); - Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point, Convert.ToByte(0)); - Icon = Resources.mRemote_Icon; - Name = "Connection"; - TabText = @"UI.Window.Connection"; - Text = @"UI.Window.Connection"; - cmenTab.ResumeLayout(false); - ResumeLayout(false); - } - #endregion - #region Public Methods - public ConnectionWindow(DockContent Panel, string FormText = "") + private void SetContextMenuEventHandlers() { - if (FormText == "") - { - FormText = Language.strNewPanel; - } - - WindowType = WindowType.Connection; - DockPnl = Panel; - InitializeComponent(); - // ReSharper disable once VirtualMemberCallInConstructor - Text = FormText; - TabText = FormText; + cmenTabFullscreen.Click += (sender, args) => ToggleFullscreen(); + cmenTabSmartSize.Click += (sender, args) => ToggleSmartSize(); + cmenTabViewOnly.Click += (sender, args) => ToggleViewOnly(); + cmenTabScreenshot.Click += (sender, args) => CreateScreenshot(); + cmenTabStartChat.Click += (sender, args) => StartChat(); + cmenTabTransferFile.Click += (sender, args) => TransferFile(); + cmenTabRefreshScreen.Click += (sender, args) => RefreshScreen(); + cmenTabSendSpecialKeysCtrlAltDel.Click += (sender, args) => SendSpecialKeys(ProtocolVNC.SpecialKeys.CtrlAltDel); + cmenTabSendSpecialKeysCtrlEsc.Click += (sender, args) => SendSpecialKeys(ProtocolVNC.SpecialKeys.CtrlEsc); + cmenTabRenameTab.Click += (sender, args) => RenameTab(); + cmenTabDuplicateTab.Click += (sender, args) => DuplicateTab(); + cmenTabReconnect.Click += (sender, args) => Reconnect(); + cmenTabDisconnect.Click += (sender, args) => CloseTabMenu(); + cmenTabPuttySettings.Click += (sender, args) => ShowPuttySettingsDialog(); } - public Crownwood.Magic.Controls.TabPage AddConnectionTab(ConnectionInfo conI) + public TabPage AddConnectionTab(ConnectionInfo connectionInfo) { try { - Crownwood.Magic.Controls.TabPage nTab = new Crownwood.Magic.Controls.TabPage(); - nTab.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top; + var nTab = new TabPage + { + Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top + }; if (Settings.Default.ShowProtocolOnTabs) - { - nTab.Title = conI.Protocol.ToString() + @": "; - } + nTab.Title = connectionInfo.Protocol + @": "; else - { nTab.Title = ""; - } - nTab.Title += conI.Name; + nTab.Title += connectionInfo.Name; if (Settings.Default.ShowLogonInfoOnTabs) { nTab.Title += @" ("; + if (connectionInfo.Domain != "") + nTab.Title += connectionInfo.Domain; - if (conI.Domain != "") + if (connectionInfo.Username != "") { - nTab.Title += conI.Domain; - } - - if (conI.Username != "") - { - if (conI.Domain != "") - { + if (connectionInfo.Domain != "") nTab.Title += @"\"; - } - - nTab.Title += conI.Username; + nTab.Title += connectionInfo.Username; } nTab.Title += @")"; @@ -310,20 +128,14 @@ namespace mRemoteNG.UI.Window nTab.Title = nTab.Title.Replace("&", "&&"); - Icon conIcon = ConnectionIcon.FromString(conI.Icon); + var conIcon = ConnectionIcon.FromString(connectionInfo.Icon); if (conIcon != null) - { nTab.Icon = conIcon; - } if (Settings.Default.OpenTabsRightOfSelected) - { TabController.TabPages.Insert(TabController.SelectedIndex + 1, nTab); - } else - { TabController.TabPages.Add(nTab); - } nTab.Selected = true; _ignoreChangeSelectedTabClick = false; @@ -332,14 +144,12 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "AddConnectionTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "AddConnectionTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } return null; } - #endregion - #region Private Methods public void UpdateSelectedConnection() { if (TabController.SelectedTab == null) @@ -348,15 +158,8 @@ namespace mRemoteNG.UI.Window } else { - InterfaceControl interfaceControl = TabController.SelectedTab.Tag as InterfaceControl; - if (interfaceControl == null) - { - frmMain.Default.SelectedConnection = null; - } - else - { - frmMain.Default.SelectedConnection = interfaceControl.Info; - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + frmMain.Default.SelectedConnection = interfaceControl?.Info; } } #endregion @@ -423,7 +226,7 @@ namespace mRemoteNG.UI.Window ((Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.All & TabController.TabPages.Count > 0) || (Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.Multiple & TabController.TabPages.Count > 1))) { - DialogResult result = CTaskDialog.MessageBox(this, GeneralAppInfo.ProdName, string.Format(Language.strConfirmCloseConnectionPanelMainInstruction, Text), "", "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.YesNo, ESysIcons.Question, ESysIcons.Question); + var result = CTaskDialog.MessageBox(this, GeneralAppInfo.ProdName, string.Format(Language.strConfirmCloseConnectionPanelMainInstruction, Text), "", "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.YesNo, ESysIcons.Question, ESysIcons.Question); if (CTaskDialog.VerificationChecked) { Settings.Default.ConfirmCloseConnection--; @@ -437,55 +240,29 @@ namespace mRemoteNG.UI.Window try { - foreach (Crownwood.Magic.Controls.TabPage tabP in TabController.TabPages) + foreach (TabPage tabP in TabController.TabPages) { - if (tabP.Tag != null) - { - InterfaceControl interfaceControl = (InterfaceControl)tabP.Tag; - interfaceControl.Protocol.Close(); - } + if (tabP.Tag == null) continue; + var interfaceControl = (InterfaceControl)tabP.Tag; + interfaceControl.Protocol.Close(); } } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "UI.Window.Connection.Connection_FormClosing() failed" + Environment.NewLine + ex.Message, true); - } - } - - private EventHandler ResizeBeginEvent; - public new event EventHandler ResizeBegin - { - add - { - ResizeBeginEvent = (EventHandler)Delegate.Combine(ResizeBeginEvent, value); - } - remove - { - ResizeBeginEvent = (EventHandler)Delegate.Remove(ResizeBeginEvent, value); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "UI.Window.Connection.Connection_FormClosing() failed" + Environment.NewLine + ex.Message, true); } } + public new event EventHandler ResizeBegin; private void Connection_ResizeBegin(object sender, EventArgs e) { - ResizeBeginEvent?.Invoke(this, e); - } - - private EventHandler ResizeEndEvent; - public new event EventHandler ResizeEnd - { - add - { - ResizeEndEvent = (EventHandler)Delegate.Combine(ResizeEndEvent, value); - } - remove - { - ResizeEndEvent = (EventHandler)Delegate.Remove(ResizeEndEvent, value); - } + ResizeBegin?.Invoke(this, e); } + public new event EventHandler ResizeEnd; private void Connection_ResizeEnd(object sender, EventArgs e) { - ResizeEndEvent?.Invoke(sender, e); + ResizeEnd?.Invoke(sender, e); } #endregion @@ -504,10 +281,11 @@ namespace mRemoteNG.UI.Window { try { - Crownwood.Magic.Controls.TabPage selectedTab = TabController.SelectedTab; + var selectedTab = TabController.SelectedTab; + if (selectedTab == null) return; if (Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.All) { - DialogResult result = CTaskDialog.MessageBox(this, GeneralAppInfo.ProdName, string.Format(Language.strConfirmCloseConnectionMainInstruction, selectedTab.Title), "", "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.YesNo, ESysIcons.Question, ESysIcons.Question); + var result = CTaskDialog.MessageBox(this, GeneralAppInfo.ProdName, string.Format(Language.strConfirmCloseConnectionMainInstruction, selectedTab.Title), "", "", "", Language.strCheckboxDoNotShowThisMessageAgain, ETaskDialogButtons.YesNo, ESysIcons.Question, ESysIcons.Question); if (CTaskDialog.VerificationChecked) { Settings.Default.ConfirmCloseConnection--; @@ -520,7 +298,7 @@ namespace mRemoteNG.UI.Window if (selectedTab.Tag != null) { - InterfaceControl interfaceControl = (InterfaceControl)selectedTab.Tag; + var interfaceControl = (InterfaceControl)selectedTab.Tag; interfaceControl.Protocol.Close(); } else @@ -530,13 +308,13 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "UI.Window.Connection.CloseConnectionTab() failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "UI.Window.Connection.CloseConnectionTab() failed" + Environment.NewLine + ex.Message, true); } UpdateSelectedConnection(); } - private void TabController_DoubleClickTab(Crownwood.Magic.Controls.TabControl sender, Crownwood.Magic.Controls.TabPage page) + private void TabController_DoubleClickTab(TabControl sender, TabPage page) { _firstClickTicks = 0; if (Settings.Default.DoubleClickOnTabClosesIt) @@ -548,22 +326,27 @@ namespace mRemoteNG.UI.Window #region Drag and Drop private void TabController_DragDrop(object sender, DragEventArgs e) { - if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", true)) + var dropDataAsOlvDataObject = e.Data as OLVDataObject; + if (dropDataAsOlvDataObject == null) return; + var modelObjects = dropDataAsOlvDataObject.ModelObjects; + foreach (var model in modelObjects) { - Runtime.OpenConnection((ConnectionInfo)((TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode", true)).Tag, this, ConnectionInfo.Force.DoNotJump); - } - } - - private void TabController_DragEnter(object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", true)) - { - e.Effect = DragDropEffects.Move; + var modelAsContainer = model as ContainerInfo; + var modelAsConnection = model as ConnectionInfo; + if (modelAsContainer != null) + ConnectionInitiator.OpenConnection(modelAsContainer); + else if (modelAsConnection != null) + ConnectionInitiator.OpenConnection(modelAsConnection); } } private void TabController_DragOver(object sender, DragEventArgs e) { + e.Effect = DragDropEffects.None; + var dropDataAsOlvDataObject = e.Data as OLVDataObject; + var modelObjects = dropDataAsOlvDataObject?.ModelObjects; + if (modelObjects == null) return; + if (!modelObjects.OfType().Any()) return; e.Effect = DragDropEffects.Move; } #endregion @@ -574,20 +357,14 @@ namespace mRemoteNG.UI.Window { try { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab?.Tag; + var interfaceControl = (InterfaceControl)TabController.SelectedTab?.Tag; + if (interfaceControl == null) return; - if (IC == null) + if (interfaceControl.Info.Protocol == ProtocolType.RDP) { - return; - } - - if (IC.Info.Protocol == ProtocolType.RDP) - { - ProtocolRDP rdp = (ProtocolRDP)IC.Protocol; - + var rdp = (ProtocolRDP)interfaceControl.Protocol; cmenTabFullscreen.Visible = true; cmenTabFullscreen.Checked = rdp.Fullscreen; - cmenTabSmartSize.Visible = true; cmenTabSmartSize.Checked = rdp.SmartSize; } @@ -597,17 +374,15 @@ namespace mRemoteNG.UI.Window cmenTabSmartSize.Visible = false; } - if (IC.Info.Protocol == ProtocolType.VNC) + if (interfaceControl.Info.Protocol == ProtocolType.VNC) { + var vnc = (ProtocolVNC)interfaceControl.Protocol; cmenTabSendSpecialKeys.Visible = true; cmenTabViewOnly.Visible = true; - cmenTabSmartSize.Visible = true; cmenTabStartChat.Visible = true; cmenTabRefreshScreen.Visible = true; cmenTabTransferFile.Visible = false; - - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; cmenTabSmartSize.Checked = vnc.SmartSize; cmenTabViewOnly.Checked = vnc.ViewOnly; } @@ -620,12 +395,12 @@ namespace mRemoteNG.UI.Window cmenTabTransferFile.Visible = false; } - if (IC.Info.Protocol == ProtocolType.SSH1 | IC.Info.Protocol == ProtocolType.SSH2) + if (interfaceControl.Info.Protocol == ProtocolType.SSH1 | interfaceControl.Info.Protocol == ProtocolType.SSH2) { cmenTabTransferFile.Visible = true; } - if (IC.Protocol is PuttyBase) + if (interfaceControl.Protocol is PuttyBase) { cmenTabPuttySettings.Visible = true; } @@ -638,86 +413,9 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "ShowHideMenuButtons (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ShowHideMenuButtons (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - - private void cmenTabScreenshot_Click(object sender, EventArgs e) - { - cmenTab.Close(); - Application.DoEvents(); - Windows.screenshotForm.AddScreenshot(Tools.MiscTools.TakeScreenshot(this)); - } - - private void cmenTabSmartSize_Click(object sender, EventArgs e) - { - ToggleSmartSize(); - } - - private void cmenTabReconnect_Click(object sender, EventArgs e) - { - Reconnect(); - } - - private void cmenTabTransferFile_Click(object sender, EventArgs e) - { - TransferFile(); - } - - private void cmenTabViewOnly_Click(object sender, EventArgs e) - { - ToggleViewOnly(); - } - - private void cmenTabStartChat_Click(object sender, EventArgs e) - { - StartChat(); - } - - private void cmenTabRefreshScreen_Click(object sender, EventArgs e) - { - RefreshScreen(); - } - - private void cmenTabSendSpecialKeysCtrlAltDel_Click(object sender, EventArgs e) - { - SendSpecialKeys(ProtocolVNC.SpecialKeys.CtrlAltDel); - } - - private void cmenTabSendSpecialKeysCtrlEsc_Click(object sender, EventArgs e) - { - SendSpecialKeys(ProtocolVNC.SpecialKeys.CtrlEsc); - } - - private void cmenTabFullscreen_Click(object sender, EventArgs e) - { - ToggleFullscreen(); - } - - private void cmenTabPuttySettings_Click(object sender, EventArgs e) - { - ShowPuttySettingsDialog(); - } - - private void cmenTabExternalAppsEntry_Click(object sender, EventArgs e) - { - StartExternalApp((Tools.ExternalTool)((ToolStripMenuItem)sender).Tag); - } - - private void cmenTabDisconnect_Click(object sender, EventArgs e) - { - CloseTabMenu(); - } - - private void cmenTabDuplicateTab_Click(object sender, EventArgs e) - { - DuplicateTab(); - } - - private void cmenTabRenameTab_Click(object sender, EventArgs e) - { - RenameTab(); - } #endregion #region Tab Actions @@ -725,26 +423,24 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; + if (!(TabController.SelectedTab?.Tag is InterfaceControl)) return; + var interfaceControl = (InterfaceControl)TabController.SelectedTab?.Tag; - var protocol = IC.Protocol as ProtocolRDP; - if (protocol != null) - { - ProtocolRDP rdp = protocol; - rdp.ToggleSmartSize(); - } - else if (IC.Protocol is ProtocolVNC) - { - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.ToggleSmartSize(); - } + var protocol = interfaceControl.Protocol as ProtocolRDP; + if (protocol != null) + { + var rdp = protocol; + rdp.ToggleSmartSize(); + } + else if (interfaceControl.Protocol is ProtocolVNC) + { + var vnc = (ProtocolVNC)interfaceControl.Protocol; + vnc.ToggleSmartSize(); } } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "ToggleSmartSize (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleSmartSize (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -752,59 +448,52 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + if (interfaceControl == null) return; - if (IC.Info.Protocol == ProtocolType.SSH1 | IC.Info.Protocol == ProtocolType.SSH2) - { - SSHTransferFile(); - } - else if (IC.Info.Protocol == ProtocolType.VNC) - { - VNCTransferFile(); - } - } + if (interfaceControl.Info.Protocol == ProtocolType.SSH1 | interfaceControl.Info.Protocol == ProtocolType.SSH2) + SshTransferFile(); + else if (interfaceControl.Info.Protocol == ProtocolType.VNC) + VncTransferFile(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "TransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "TransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - private void SSHTransferFile() + private void SshTransferFile() { try { - - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + if (interfaceControl == null) return; Windows.Show(WindowType.SSHTransfer); + var connectionInfo = interfaceControl.Info; - ConnectionInfo conI = IC.Info; - - Windows.sshtransferForm.Hostname = conI.Hostname; - Windows.sshtransferForm.Username = conI.Username; - Windows.sshtransferForm.Password = conI.Password; - Windows.sshtransferForm.Port = Convert.ToString(conI.Port); + Windows.SshtransferForm.Hostname = connectionInfo.Hostname; + Windows.SshtransferForm.Username = connectionInfo.Username; + Windows.SshtransferForm.Password = connectionInfo.Password; + Windows.SshtransferForm.Port = Convert.ToString(connectionInfo.Port); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "SSHTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SSHTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - private void VNCTransferFile() + private void VncTransferFile() { try { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.StartFileTransfer(); + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var vnc = interfaceControl?.Protocol as ProtocolVNC; + vnc?.StartFileTransfer(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "VNCTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "VNCTransferFile (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -812,22 +501,15 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - - if (IC.Protocol is ProtocolVNC) - { - cmenTabViewOnly.Checked = !cmenTabViewOnly.Checked; - - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.ToggleViewOnly(); - } - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var vnc = interfaceControl?.Protocol as ProtocolVNC; + if (vnc == null) return; + cmenTabViewOnly.Checked = !cmenTabViewOnly.Checked; + vnc.ToggleViewOnly(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "ToggleViewOnly (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleViewOnly (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -835,17 +517,13 @@ namespace mRemoteNG.UI.Window { try { - InterfaceControl IC = TabController.SelectedTab?.Tag as InterfaceControl; - - if (IC?.Protocol is ProtocolVNC) - { - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.StartChat(); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var vnc = interfaceControl?.Protocol as ProtocolVNC; + vnc?.StartChat(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "StartChat (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "StartChat (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -853,35 +531,27 @@ namespace mRemoteNG.UI.Window { try { - InterfaceControl IC = TabController.SelectedTab?.Tag as InterfaceControl; - - if (IC?.Protocol is ProtocolVNC) - { - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.RefreshScreen(); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var vnc = interfaceControl?.Protocol as ProtocolVNC; + vnc?.RefreshScreen(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "RefreshScreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RefreshScreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - private void SendSpecialKeys(ProtocolVNC.SpecialKeys Keys) + private void SendSpecialKeys(ProtocolVNC.SpecialKeys keys) { try { - InterfaceControl IC = TabController.SelectedTab?.Tag as InterfaceControl; - - if (IC?.Protocol is ProtocolVNC) - { - ProtocolVNC vnc = (ProtocolVNC)IC.Protocol; - vnc.SendSpecialKeys(Keys); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var vnc = interfaceControl?.Protocol as ProtocolVNC; + vnc?.SendSpecialKeys(keys); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "SendSpecialKeys (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "SendSpecialKeys (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -889,17 +559,13 @@ namespace mRemoteNG.UI.Window { try { - InterfaceControl IC = TabController.SelectedTab?.Tag as InterfaceControl; - - if (IC?.Protocol is ProtocolRDP) - { - ProtocolRDP rdp = (ProtocolRDP)IC.Protocol; - rdp.ToggleFullscreen(); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var rdp = interfaceControl?.Protocol as ProtocolRDP; + rdp?.ToggleFullscreen(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "ToggleFullscreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ToggleFullscreen (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -907,18 +573,13 @@ namespace mRemoteNG.UI.Window { try { - InterfaceControl objInterfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; - - if (objInterfaceControl?.Protocol is PuttyBase) - { - PuttyBase objPuttyBase = (PuttyBase)objInterfaceControl.Protocol; - - objPuttyBase.ShowSettingsDialog(); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + var puttyBase = interfaceControl?.Protocol as PuttyBase; + puttyBase?.ShowSettingsDialog(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "ShowPuttySettingsDialog (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "ShowPuttySettingsDialog (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -926,33 +587,28 @@ namespace mRemoteNG.UI.Window { try { - //clean up - //since new items are added below, we have to dispose of any previous items first + //clean up. since new items are added below, we have to dispose of any previous items first if (cmenTabExternalApps.DropDownItems.Count > 0) { - for (int i = cmenTabExternalApps.DropDownItems.Count - 1; i >= 0; i--) + for (var i = cmenTabExternalApps.DropDownItems.Count - 1; i >= 0; i--) cmenTabExternalApps.DropDownItems[i].Dispose(); - cmenTabExternalApps.DropDownItems.Clear(); } - //add ext apps - foreach (Tools.ExternalTool extA in Runtime.ExternalTools) + foreach (ExternalTool externalTool in Runtime.ExternalTools) { - ToolStripMenuItem nItem = new ToolStripMenuItem + var nItem = new ToolStripMenuItem { - Text = extA.DisplayName, - Tag = extA, + Text = externalTool.DisplayName, + Tag = externalTool, /* rare failure here. While ExternalTool.Image already tries to default this * try again so it's not null/doesn't crash. */ - Image = extA.Image ?? Resources.mRemote_Icon.ToBitmap() + Image = externalTool.Image ?? Resources.mRemote_Icon.ToBitmap() }; - - nItem.Click += cmenTabExternalAppsEntry_Click; - + nItem.Click += (sender, args) => StartExternalApp(((ToolStripMenuItem)sender).Tag as ExternalTool); cmenTabExternalApps.DropDownItems.Add(nItem); } } @@ -962,19 +618,16 @@ namespace mRemoteNG.UI.Window } } - private void StartExternalApp(Tools.ExternalTool ExtA) + private void StartExternalApp(ExternalTool externalTool) { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - ExtA.Start(IC.Info); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + externalTool.Start(interfaceControl?.Info); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "cmenTabExternalAppsEntry_Click failed (UI.Window.ConnectionWindow)" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "cmenTabExternalAppsEntry_Click failed (UI.Window.ConnectionWindow)" + Environment.NewLine + ex.Message, true); } } @@ -982,15 +635,12 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - IC.Protocol.Close(); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + interfaceControl?.Protocol.Close(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "CloseTabMenu (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "CloseTabMenu (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -998,16 +648,14 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - Runtime.OpenConnection(IC.Info, ConnectionInfo.Force.DoNotJump); - _ignoreChangeSelectedTabClick = false; - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + if (interfaceControl == null) return; + ConnectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); + _ignoreChangeSelectedTabClick = false; } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "DuplicateTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "DuplicateTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -1015,16 +663,14 @@ namespace mRemoteNG.UI.Window { try { - if (TabController.SelectedTab?.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - IC.Protocol.Close(); - Runtime.OpenConnection(IC.Info, ConnectionInfo.Force.DoNotJump); - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + if (interfaceControl == null) return; + interfaceControl.Protocol.Close(); + ConnectionInitiator.OpenConnection(interfaceControl.Info, ConnectionInfo.Force.DoNotJump); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Reconnect (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Reconnect (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } @@ -1032,63 +678,69 @@ namespace mRemoteNG.UI.Window { try { - string nTitle = ""; - - if (input.InputBox(Language.strNewTitle, Language.strNewTitle + ":", ref nTitle) == DialogResult.OK && !string.IsNullOrEmpty(nTitle)) - { - TabController.SelectedTab.Title = nTitle.Replace("&", "&&"); - } + var newTitle = ""; + if (input.InputBox(Language.strNewTitle, Language.strNewTitle + ":", ref newTitle) == DialogResult.OK && !string.IsNullOrEmpty(newTitle)) + TabController.SelectedTab.Title = newTitle.Replace("&", "&&"); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "RenameTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RenameTab (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } + + private void CreateScreenshot() + { + cmenTab.Close(); + Application.DoEvents(); + Windows.ScreenshotForm.AddScreenshot(MiscTools.TakeScreenshot(this)); + } #endregion #region Protocols public void Prot_Event_Closed(object sender) { - ProtocolBase Prot = (ProtocolBase)sender; - CloseTab((Crownwood.Magic.Controls.TabPage)Prot.InterfaceControl.Parent); + var protocolBase = sender as ProtocolBase; + var tabPage = protocolBase?.InterfaceControl.Parent as TabPage; + if (tabPage != null) + CloseTab(tabPage); } #endregion #region Tabs - private delegate void CloseTabCB(Crownwood.Magic.Controls.TabPage TabToBeClosed); - private void CloseTab(Crownwood.Magic.Controls.TabPage TabToBeClosed) + private delegate void CloseTabDelegate(TabPage tabToBeClosed); + private void CloseTab(TabPage tabToBeClosed) { if (TabController.InvokeRequired) { - CloseTabCB s = CloseTab; + CloseTabDelegate s = CloseTab; try { - TabController.Invoke(s, TabToBeClosed); + TabController.Invoke(s, tabToBeClosed); } - catch (System.Runtime.InteropServices.COMException) + catch (COMException) { - TabController.Invoke(s, TabToBeClosed); + TabController.Invoke(s, tabToBeClosed); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); } } else { try { - TabController.TabPages.Remove(TabToBeClosed); + TabController.TabPages.Remove(tabToBeClosed); _ignoreChangeSelectedTabClick = false; } - catch (System.Runtime.InteropServices.COMException) + catch (COMException) { - CloseTab(TabToBeClosed); + CloseTab(tabToBeClosed); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "Couldn\'t close tab" + Environment.NewLine + ex.Message, true); } if (TabController.TabPages.Count == 0) @@ -1103,8 +755,8 @@ namespace mRemoteNG.UI.Window { _ignoreChangeSelectedTabClick = true; UpdateSelectedConnection(); - FocusIC(); - RefreshIC(); + FocusInterfaceController(); + RefreshInterfaceController(); } private int _firstClickTicks; @@ -1115,7 +767,7 @@ namespace mRemoteNG.UI.Window { if (!(NativeMethods.GetForegroundWindow() == frmMain.Default.Handle) && !_ignoreChangeSelectedTabClick) { - Crownwood.Magic.Controls.TabPage clickedTab = TabController.TabPageFromPoint(e.Location); + var clickedTab = TabController.TabPageFromPoint(e.Location); if (clickedTab != null && TabController.SelectedTab != clickedTab) { NativeMethods.SetForegroundWindow(Handle); @@ -1127,13 +779,13 @@ namespace mRemoteNG.UI.Window switch (e.Button) { case MouseButtons.Left: - int currentTicks = Environment.TickCount; - int elapsedTicks = currentTicks - _firstClickTicks; + var currentTicks = Environment.TickCount; + var elapsedTicks = currentTicks - _firstClickTicks; if (elapsedTicks > SystemInformation.DoubleClickTime || !_doubleClickRectangle.Contains(MousePosition)) { _firstClickTicks = currentTicks; _doubleClickRectangle = new Rectangle(MousePosition.X - (SystemInformation.DoubleClickSize.Width / 2), MousePosition.Y - (SystemInformation.DoubleClickSize.Height / 2), SystemInformation.DoubleClickSize.Width, SystemInformation.DoubleClickSize.Height); - FocusIC(); + FocusInterfaceController(); } else { @@ -1144,6 +796,7 @@ namespace mRemoteNG.UI.Window CloseConnectionTab(); break; case MouseButtons.Right: + if (TabController.SelectedTab?.Tag == null) return; ShowHideMenuButtons(); NativeMethods.SetForegroundWindow(Handle); cmenTab.Show(TabController, e.Location); @@ -1152,49 +805,34 @@ namespace mRemoteNG.UI.Window } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "TabController_MouseUp (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "TabController_MouseUp (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - private void FocusIC() + private void FocusInterfaceController() { try { - if (TabController.SelectedTab != null) - { - if (TabController.SelectedTab.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - IC.Protocol.Focus(); - } - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + interfaceControl?.Protocol?.Focus(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "FocusIC (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "FocusIC (UI.Window.ConnectionWindow) failed" + Environment.NewLine + ex.Message, true); } } - public void RefreshIC() + public void RefreshInterfaceController() { try { - if (TabController.SelectedTab != null) - { - if (TabController.SelectedTab.Tag is InterfaceControl) - { - InterfaceControl IC = (InterfaceControl)TabController.SelectedTab.Tag; - - if (IC.Info.Protocol == ProtocolType.VNC) - { - ((ProtocolVNC)IC.Protocol).RefreshScreen(); - } - } - } + var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl; + if (interfaceControl?.Info.Protocol == ProtocolType.VNC) + ((ProtocolVNC)interfaceControl.Protocol).RefreshScreen(); } catch (Exception ex) { - Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg, "RefreshIC (UI.Window.Connection) failed" + Environment.NewLine + ex.Message, true); + Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, "RefreshIC (UI.Window.Connection) failed" + Environment.NewLine + ex.Message, true); } } #endregion @@ -1206,20 +844,17 @@ namespace mRemoteNG.UI.Window { if (m.Msg == NativeMethods.WM_MOUSEACTIVATE) { - Crownwood.Magic.Controls.TabPage selectedTab = TabController.SelectedTab; - if (selectedTab != null) + var selectedTab = TabController.SelectedTab; + if (selectedTab == null) return; { - Rectangle tabClientRectangle = selectedTab.RectangleToScreen(selectedTab.ClientRectangle); + var tabClientRectangle = selectedTab.RectangleToScreen(selectedTab.ClientRectangle); if (tabClientRectangle.Contains(MousePosition)) { - InterfaceControl interfaceControl = TabController.SelectedTab.Tag as InterfaceControl; - if (interfaceControl != null && interfaceControl.Info != null) + var interfaceControl = selectedTab.Tag as InterfaceControl; + if (interfaceControl?.Info?.Protocol == ProtocolType.RDP) { - if (interfaceControl.Info.Protocol == ProtocolType.RDP) - { - interfaceControl.Protocol.Focus(); - return; // Do not pass to base class - } + interfaceControl.Protocol.Focus(); + return; // Do not pass to base class } } } @@ -1235,18 +870,8 @@ namespace mRemoteNG.UI.Window #endregion #region Tab drag and drop - private bool _InTabDrag; - public bool InTabDrag - { - get - { - return _InTabDrag; - } - set - { - _InTabDrag = value; - } - } + public bool InTabDrag { get; set; } + private void TabController_PageDragStart(object sender, MouseEventArgs e) { Cursor = Cursors.SizeWE; @@ -1256,15 +881,13 @@ namespace mRemoteNG.UI.Window { InTabDrag = true; // For some reason PageDragStart gets raised again after PageDragEnd so set this here instead - Crownwood.Magic.Controls.TabPage sourceTab = TabController.SelectedTab; - Crownwood.Magic.Controls.TabPage destinationTab = TabController.TabPageFromPoint(e.Location); + var sourceTab = TabController.SelectedTab; + var destinationTab = TabController.TabPageFromPoint(e.Location); if (!TabController.TabPages.Contains(destinationTab) || sourceTab == destinationTab) - { return; - } - int targetIndex = TabController.TabPages.IndexOf(destinationTab); + var targetIndex = TabController.TabPages.IndexOf(destinationTab); TabController.TabPages.SuspendEvents(); TabController.TabPages.Remove(sourceTab); @@ -1277,9 +900,9 @@ namespace mRemoteNG.UI.Window { Cursor = Cursors.Default; InTabDrag = false; - InterfaceControl interfaceControl = TabController.SelectedTab.Tag as InterfaceControl; + var interfaceControl = TabController?.SelectedTab?.Tag as InterfaceControl; interfaceControl?.Protocol.Focus(); } #endregion } -} +} \ No newline at end of file diff --git a/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs b/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs index df5119719..55f41c87c 100644 --- a/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs +++ b/mRemoteV1/UI/Window/ErrorAndInfoWindow.cs @@ -321,7 +321,7 @@ namespace mRemoteNG.UI.Window } else { - Windows.treeForm.Show(frmMain.Default.pnlDock); + Windows.TreeForm.Show(frmMain.Default.pnlDock); } } catch (Exception) diff --git a/mRemoteV1/UI/Window/PortScanWindow.cs b/mRemoteV1/UI/Window/PortScanWindow.cs index e3b640390..073bebb5c 100644 --- a/mRemoteV1/UI/Window/PortScanWindow.cs +++ b/mRemoteV1/UI/Window/PortScanWindow.cs @@ -4,6 +4,7 @@ using System.Windows.Forms; using WeifenLuo.WinFormsUI.Docking; using mRemoteNG.App; using mRemoteNG.Connection.Protocol; +using mRemoteNG.Container; using mRemoteNG.Messages; using mRemoteNG.Tools; using static mRemoteNG.Tools.MiscTools; @@ -68,7 +69,7 @@ namespace mRemoteNG.UI.Window #endregion #region Private Fields - private Scanner _portScanner; + private PortScanner _portScanner; private bool _scanning; #endregion @@ -170,7 +171,7 @@ namespace mRemoteNG.UI.Window System.Net.IPAddress ipAddressStart = System.Net.IPAddress.Parse(ipStart.Text); System.Net.IPAddress ipAddressEnd = System.Net.IPAddress.Parse(ipEnd.Text); - _portScanner = new Scanner(ipAddressStart, ipAddressEnd, (int) portStart.Value, (int) portEnd.Value); + _portScanner = new PortScanner(ipAddressStart, ipAddressEnd, (int) portStart.Value, (int) portEnd.Value); _portScanner.BeginHostScan += PortScanner_BeginHostScan; _portScanner.HostScanned += PortScanner_HostScanned; @@ -244,7 +245,7 @@ namespace mRemoteNG.UI.Window private void importSelectedHosts(ProtocolType protocol) { - List hosts = new List(); + var hosts = new List(); foreach (ListViewItem item in lvHosts.SelectedItems) { var scanHost = (ScanHost)item.Tag; @@ -260,7 +261,8 @@ namespace mRemoteNG.UI.Window return; } - Import.ImportFromPortScan(hosts, protocol); + var selectedTreeNodeAsContainer = Windows.TreeForm.SelectedNode as ContainerInfo ?? Windows.TreeForm.SelectedNode.Parent; + Import.ImportFromPortScan(hosts, protocol, selectedTreeNodeAsContainer); } private void importVNCToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 39b86078c..4ebf0c10a 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -72,6 +72,10 @@ References\MagicLibrary.dll True + + ..\packages\ObjectListView.Official.2.9.1\lib\net20\ObjectListView.dll + True + ..\packages\SSH.NET.2016.0.0\lib\net40\Renci.SshNet.dll True @@ -81,6 +85,7 @@ + @@ -122,15 +127,34 @@ + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + @@ -139,25 +163,28 @@ - + - - - - - - - - - - + + + + + + + + + + + + + - + @@ -169,15 +196,21 @@ - + + + - - + + + + - + + Component + Component @@ -261,7 +294,7 @@ - + @@ -272,7 +305,6 @@ Component - @@ -293,7 +325,6 @@ - @@ -314,7 +345,6 @@ Form - True True @@ -358,7 +388,6 @@ - Component @@ -402,6 +431,9 @@ Form + + ConnectionWindow.cs + Form diff --git a/mRemoteV1/packages.config b/mRemoteV1/packages.config index 14b47134f..29e9c4d93 100644 --- a/mRemoteV1/packages.config +++ b/mRemoteV1/packages.config @@ -4,5 +4,6 @@ + \ No newline at end of file