private void OnConnectNode_MenuItemClick(object sender, EventArgs e) { if (ContextNode == null) { return; } try { if (ContextNode.Tag is Slave) { Slave ss = ContextNode.Tag as Slave; ss.Connect(false, UserCredentials); } else if (ContextNode.Tag is HostGroup) { HostGroup Group = ContextNode.Tag as HostGroup; foreach (Slave ss in Group.Slaves) { ss.Connect(false, UserCredentials); } } else { return; } } catch (Exception ex) { MessageBox.Show("Unable to connect: " + ex.ToString()); } }
void Slave_Connection_OnMessage(Slave_Connection SC, System.Xml.Linq.XElement xMsg) { // This event is called from an independent thread belonging to the particular slave. #if DEBUG // In the startup debugging phase, intercept anything and queue it for later. if (StartupDebugging) { lock (this) { DebugQueue.Enqueue(new Tuple <Slave_Connection, System.Xml.Linq.XElement>(SC, xMsg)); } return; } #endif Slave found = null; lock (Slaves) { foreach (Slave ss in Slaves) { if (ss.Connection == SC) { found = ss; break; } } } if (found != null) //lock (found) { Terminal.OnMessage(found, xMsg); return; } throw new Exception("Slave not found in current connections list."); }
private void OnDisconnectNode_MenuItemClick(object sender, EventArgs e) { if (ContextNode == null) { return; } try { if (ContextNode.Tag is Slave) { Slave ss = ContextNode.Tag as Slave; ss.Disconnect(); } else if (ContextNode.Tag is HostGroup) { HostGroup Group = ContextNode.Tag as HostGroup; foreach (Slave ss in Group.Slaves) { ss.Disconnect(); } } else { return; } } catch (Exception ex) { MessageBox.Show("Error while disconnecting: " + ex.ToString()); } }
void SaveHostListToRegistry() { lock (Slaves) { lock (ComputerTree) { // Clear any existing registry entries that are no longer present. using (RegistryKey key = Registry.CurrentUser.OpenSubKey(HostRegSubKey, true)) { if (key != null) { string[] subkeys = key.GetSubKeyNames(); foreach (string subkey in subkeys) { bool StillPresent = false; foreach (TreeNode tn in HostNodes.Nodes) { Slave ThatSlave = (Slave)tn.Tag; if (subkey == ThatSlave.HostName) { StillPresent = true; break; } } if (!StillPresent) { key.DeleteSubKey(subkey); } } } } // Create the listing. using (RegistryKey key = Registry.CurrentUser.CreateSubKey(HostRegSubKey)) { foreach (TreeNode tn in HostNodes.Nodes) { Slave ThatSlave = (Slave)tn.Tag; if (ThatSlave.HostName == "localhost") { continue; } key.CreateSubKey(ThatSlave.HostName); } } } } }
private void addHostStripMenuItem_Click(object sender, EventArgs e) { AddHostForm ahf = new AddHostForm(Groups, LastAdditions); if (ahf.ShowDialog() != DialogResult.OK) { return; } LastAdditions = ahf.Membership; Slave NewSlave = new Slave(ahf.HostName, AcceptedCertificates); lock (Slaves) { NewSlave.Connection.OnMessage += Slave_Connection_OnMessage; NewSlave.Connection.OnConnectionState += Slave_Connection_OnState; Slaves.Add(NewSlave); lock (ComputerTree) { Terminal.AddSlave(NewSlave); string Display = NewSlave.HostName + " (Disconnected)"; TreeNode SlaveNode = new TreeNode(Display); SlaveNode.Tag = NewSlave; HostNodes.Nodes.Add(SlaveNode); foreach (HostGroup Group in LastAdditions) { Group.Slaves.Add(NewSlave); List <TreeNode> Instances = FindAllInstancesOfGroup(Group.Name); foreach (TreeNode tn in Instances) { TreeNode GNode = new TreeNode(Display); GNode.Tag = NewSlave; tn.Nodes.Add(GNode); tn.Text = Group.GetDisplayText(); } } Legend.Invalidate(); } } SaveHostListToRegistry(); SaveGroupListToRegistry(); }
protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); Graphics g = pe.Graphics; const int LeftMargin = 10; SizeF szGenericText = g.MeasureString("gY", Font); int ClientHeight = ClientRectangle.Height; int TopMargin = (int)(ClientHeight / 2 - szGenericText.Height / 2); int VerticalBarMargin = 5; if (Source == null) { g.DrawString("No source provided.", Font, Brushes.Black, new PointF(LeftMargin, TopMargin)); return; } List <Slave> Markers = Source.GetMarkerLegend(); int xx = LeftMargin; int MarkerWidth = 4; int TextMargin = 3; int BetweenMarkers = 8; for (int ii = 0; ii < Markers.Count; ii++) { Slave ss = Markers[ii]; Rectangle rr = new Rectangle(xx, VerticalBarMargin, MarkerWidth, ClientHeight - 2 * VerticalBarMargin); g.FillRectangle(new SolidBrush(ss.DarkColor), rr); xx += MarkerWidth + TextMargin; g.DrawString(ss.HostName, Font, Brushes.Black, new PointF(xx, TopMargin)); SizeF szText = g.MeasureString(ss.HostName, Font); xx += (int)szText.Width; xx += TextMargin + BetweenMarkers; } }
void RemoveHost(Slave ss) { lock (Slaves) { lock (ComputerTree) { List <TreeNode> Instances = FindAllInstancesOfSlave(ss.HostName); Slaves.Remove(ss); Terminal.RemoveSlave(ss); foreach (TreeNode tn in Instances) { TreeNode Parent = tn.Parent; Parent.Nodes.Remove(tn); if (Parent.Tag as HostGroup != null) { Parent.Text = ((HostGroup)Parent.Tag).GetDisplayText(); } } Legend.Invalidate(); } } }
private void OnRemoveNode_MenuItemClick(object sender, EventArgs e) { if (ContextNode == null) { return; } if (ContextNode.Tag is Slave) { Slave ss = ContextNode.Tag as Slave; // Removing a slave... if (MessageBox.Show("Remove the host '" + ss.HostName + "'?", "Please confirm", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } lock (ComputerTree) { List <TreeNode> Instances = FindAllInstancesOfSlave(ss.HostName); if (Instances.Count > 1) { if (MessageBox.Show("The host '" + ss.HostName + "' is a member of " + (Instances.Count - 1).ToString() + " groups. Are you sure you want to remove it from all listings?", "Please confirm", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } } } RemoveHost(ss); } else { HostGroup Group = ContextNode.Tag as HostGroup; if (Group == null) { return; } // Removing a group... if (MessageBox.Show("Remove the group '" + Group.Name + "'?", "Please confirm", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } bool AlsoHosts = false; switch (MessageBox.Show("Do you also want to remove all hosts that are part of the group '" + Group.Name + "'?", "Please confirm", MessageBoxButtons.YesNoCancel)) { case DialogResult.Yes: AlsoHosts = true; break; case DialogResult.No: AlsoHosts = false; break; case DialogResult.Cancel: return; default: return; } lock (Slaves) { lock (ComputerTree) { if (AlsoHosts) { foreach (Slave ss in Group.Slaves) { RemoveHost(ss); } } List <TreeNode> Instances = FindAllInstancesOfGroup(Group.Name); foreach (TreeNode tnGroup in Instances) { tnGroup.Parent.Nodes.Remove(tnGroup); } Groups.Remove(Group); Legend.Invalidate(); } } } SaveHostListToRegistry(); SaveGroupListToRegistry(); }
private void OnEditMembership_MenuItemClick(object sender, EventArgs e) { if (ContextNode == null) { return; } Slave ss = ContextNode.Tag as Slave; if (ss == null) { return; } List <HostGroup> Memberships = new List <HostGroup>(); lock (Slaves) { lock (ComputerTree) { foreach (TreeNode v in GroupNodes.Nodes) { HostGroup Group = v.Tag as HostGroup; if (Group.Slaves.Contains(ss)) { Memberships.Add(Group); } } } } AddHostForm ahf = new AddHostForm(Groups, Memberships); ahf.HostName = ss.HostName; if (ahf.ShowDialog() != DialogResult.OK) { return; } Memberships = ahf.Membership; lock (Slaves) { lock (ComputerTree) { List <TreeNode> ExistingInstances = FindAllInstancesOfSlave(ss.HostName); foreach (TreeNode tnGroup in GroupNodes.Nodes) { HostGroup Group = (HostGroup)tnGroup.Tag; if (Memberships.Contains(Group)) { if (!Group.Slaves.Contains(ss)) { // New membership added... Group.Slaves.Add(ss); TreeNode GNode = new TreeNode(ContextNode.Text); GNode.Tag = ss; tnGroup.Nodes.Add(GNode); tnGroup.Text = Group.GetDisplayText(); } } else { if (Group.Slaves.Contains(ss)) { // Existing membership revoked... Group.Slaves.Remove(ss); List <TreeNode> hits = new List <TreeNode>(); foreach (TreeNode tnHosts in tnGroup.Nodes) { if (((Slave)tnHosts.Tag).HostName == ss.HostName) { hits.Add(tnHosts); } } foreach (TreeNode tn in hits) { tnGroup.Nodes.Remove(tn); } tnGroup.Text = Group.GetDisplayText(); } } } Legend.Invalidate(); } } SaveHostListToRegistry(); SaveGroupListToRegistry(); }
private void MainForm_Load(object sender, EventArgs e) { try { RegistryKey key = Registry.CurrentUser.OpenSubKey(AppRegSubKey); Left = (int)key.GetValue("MainForm_Left", Left); Top = (int)key.GetValue("MainForm_Top", Top); Width = (int)key.GetValue("MainForm_Width", Width); Height = (int)key.GetValue("MainForm_Height", Height); MainSplitContainer.SplitterDistance = (int)key.GetValue("MainForm_SplitterDistance", MainSplitContainer.SplitterDistance); Terminal.TextFontSizeInPoints = (int)key.GetValue("Terminal_TextFontSize", (int)Terminal.TextFontSizeInPoints); } catch (Exception) { MainSplitContainer_Resize(null, null); } try { Show(); CredentialsDialog cd = new CredentialsDialog(this); cd.Caption = "Please provide the account to use upon connecting."; cd.Message = "Enter credentials."; if (cd.ShowDialog() != DialogResult.OK) { Close(); return; } UserCredentials = cd.Credentials; lock (Slaves) { lock (ComputerTree) { ComputerTree.Nodes.Add(HostNodes); ComputerTree.Nodes.Add(GroupNodes); // Add a LocalHost slave running in this process. Looks just like the service, but runs whenever parallel terminal is running- just in case // the user wants to run something to include localhost. LocalHostSlave = new SlaveCore(this, true); // Add all slaves and only start connecting them after they've all been added. This ensures proper semantics in the TerminalControl. Slaves.Add(new Slave("localhost", AcceptedCertificates)); // Find all other hosts that we've previously opened and use RegistryKey key = Registry.CurrentUser.OpenSubKey(HostRegSubKey, false); if (key != null) { foreach (var v in key.GetSubKeyNames()) { Slave NewSlave = new Slave(v, AcceptedCertificates); Slaves.Add(NewSlave); } } foreach (Slave ss in Slaves) { ss.Connection.OnMessage += Slave_Connection_OnMessage; ss.Connection.OnConnectionState += Slave_Connection_OnState; Terminal.AddSlave(ss); TreeNode SlaveNode = new TreeNode(ss.HostName + " (Disconnected)"); SlaveNode.Tag = ss; SlaveNode.Checked = false; HostNodes.Nodes.Add(SlaveNode); } // Find all groups we've previously had and restore them key = Registry.CurrentUser.OpenSubKey(GroupsRegSubKey, false); if (key != null) { foreach (var v in key.GetSubKeyNames()) { var group_key = key.OpenSubKey(v, false); HostGroup Group = new HostGroup(v); Groups.Add(Group); TreeNode GNode = new TreeNode(group_key + " (Disconnected)"); GNode.Tag = Group; object HostList = group_key.GetValue("Includes-Hosts"); if (HostList as string != null) { string[] HostNames = ((string)HostList).Split(new char[] { ';' }); foreach (string HostName in HostNames) { Slave Match = null; foreach (Slave ss in Slaves) { if (ss.HostName == HostName) { Match = ss; break; } } if (Match != null) { Group.Slaves.Add(Match); TreeNode HNode = new TreeNode(Match.HostName + " (Disconnected)"); HNode.Tag = Match; HNode.Checked = false; GNode.Nodes.Add(HNode); } } } GNode.Text = Group.GetDisplayText(); GroupNodes.Nodes.Add(GNode); } } GUITimer.Enabled = true; ComputerTree.ExpandAll(); Legend.Invalidate(); Terminal.Focus(); Terminal.Select(); } } ComputerTree_AfterCheck(null, null); if (!IsOnScreen(this)) { Top = 10; Left = 10; Width = 1000; Height = 1000; } Application.DoEvents(); // Clear out any keyboard events. Terminal.Enabled = true; // Enable keyboard input after dialog box. } catch (Exception ex) { MessageBox.Show(ex.ToString()); Close(); } }
//bool PendingSelfTest = true; #endif private void GUITimer_Tick(object sender, EventArgs e) { /** Process startup diagnostics when appropriate **/ #if DEBUG /* * if (PendingSelfTest && SinceCredentials.ElapsedMilliseconds > 3000) * { * Terminal.SelfTest(); * PendingSelfTest = false; * } * else if (StartupDebugging && SinceCredentials.ElapsedMilliseconds > 3200) * { * StartupDebugging = false; * FinishDebugTests(); * } */ #endif /** Process any exceptions that happened on slave worker threads **/ foreach (Slave ss in Slaves) { Exception LastError = ss.Connection.GetLastError(); if (LastError != null) { if (LastError is Slave_Connection.ConnectionException) { MessageBox.Show(LastError.Message); } else { MessageBox.Show("Error processing connection to " + ss.HostName + ": " + LastError.ToString()); } ss.Disconnect(); } } /** Process any queued state changes **/ lock (StateQueueLock) { while (StateChanges.Count > 0) { var SCI = StateChanges.Dequeue(); Slave CurrentSlave = FindSlave(SCI.Item1); if (CurrentSlave == null) { throw new ArgumentException("Connection state changed for host not found in listing."); } lock (ComputerTree) { foreach (TreeNode CurrentNode in FindAllInstancesOfSlave(CurrentSlave.HostName)) { switch (SCI.Item2) { case Slave_Connection.Connection_State.Connecting: { CurrentNode.Text = CurrentSlave.HostName + " (Connecting)"; break; } case Slave_Connection.Connection_State.EncryptionEstablished: { CurrentNode.Text = CurrentSlave.HostName + " (Connecting Terminal)"; break; } case Slave_Connection.Connection_State.Connected: { CurrentNode.Text = CurrentSlave.HostName; break; } case Slave_Connection.Connection_State.Disconnected: { CurrentNode.Text = CurrentSlave.HostName + " (Disconnected)"; break; } default: throw new NotSupportedException(); } TreeNode tnGroup = CurrentNode.Parent; if (!(tnGroup.Tag is HostGroup)) { continue; } tnGroup.Text = ((HostGroup)tnGroup.Tag).GetDisplayText(); } } } } }
private void ComputerTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button != MouseButtons.Right) { return; } Point MousePos = e.Location; ContextNode = e.Node; Slave ContextSlave = ContextNode.Tag as Slave; HostGroup ContextGroup = ContextNode.Tag as HostGroup; MenuItem miConnect = new MenuItem("&Connect", OnConnectNode_MenuItemClick); MenuItem miDisconnect = new MenuItem("&Disconnect", OnDisconnectNode_MenuItemClick); MenuItem miSep = new MenuItem("-"); MenuItem miEditGroups = new MenuItem("Change &Group Memberships...", OnEditMembership_MenuItemClick); MenuItem miRemove = new MenuItem("&Remove Host", OnRemoveNode_MenuItemClick); MenuItem[] menuItems; if (ContextSlave != null) { miConnect.Enabled = ContextSlave.IsDisconnected; miDisconnect.Enabled = !ContextSlave.IsDisconnected; menuItems = new MenuItem[] { miConnect, miDisconnect, miSep, miEditGroups, miRemove }; } else if (ContextGroup != null) { miRemove.Text = "&Remove Group"; miConnect.Enabled = ContextGroup.CanConnect; miDisconnect.Enabled = ContextGroup.CanDisconnect; menuItems = new MenuItem[] { miConnect, miDisconnect, miSep, miRemove }; } else if (e.Node == HostNodes) { MenuItem miAdd = new MenuItem("&Add Host", addHostStripMenuItem_Click); menuItems = new MenuItem[] { miAdd }; } else if (e.Node == GroupNodes) { MenuItem miAdd = new MenuItem("&Add Group", addGroupToolStripMenuItem_Click); menuItems = new MenuItem[] { miAdd }; } else { return; } ContextMenu buttonMenu = new ContextMenu(menuItems); buttonMenu.Show(ComputerTree, MousePos); }