diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c4efe2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa3c8e1 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Registry Editor + +Registry Editor is a small utility that will help you finding specific registries with a specific search criteria.
+All the results will be showen in one place and you can then delete the selected registries or right click on one of the results will open +the official Windows regedit in the location of the selected registry. NOTE: When deleting registries, a backup will automatically be +created on your desktop. + + +## Motivation + +If you're here, I guess you already aware that the official build in registry editor(regedit) in Windows allows you to only `Find Next` +and searching for `Keys`, `Values` and `Data`.
+That sometimes can be very time consuming when you look for specific registry, therefore writing a quick gui application to add all +these results in one place wouldn't take much time so I can just let it scan through with more advanced filters and do with the results +whatever comes in mind, i.e deleting found results, saving, jumping directly to the official registry location etc...
+I also have to give credit to my brother that asked for a simple script to scan through the registry on a specific criteria, which brought +me to the idea of writing a gui application that will be much easier to maintain and extend if needed. + +Another useful situation is when you install a new software and you want to look for any registers that the software installed on your +machine, which can be easily tracked down by scanning the whole registry and finding their existing locations. + +## Pictures + +![alt text][img_main] + +![alt text][img_edit] + +![alt text][img_network] + +[img_main]: pictures/mainwindow.png +[img_edit]: pictures/findwindow.png +[img_network]: pictures/networkwindow.png \ No newline at end of file diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..9d4e0a4 --- /dev/null +++ b/build.bat @@ -0,0 +1,21 @@ +@echo off + + +set BUILD_TYPE=%1 + +if not "%BUILD_TYPE%" == "Debug" ( + echo Building in Release mode. + set BUILD_TYPE=Release +) else ( + echo Building in Debug mode. +) + +WHERE msbuild +if %ERRORLEVEL% NEQ 0 ( + echo ### ERROR: Run Developer Command Prompt for VS and try again. ### +) else ( + cd /d %~dp0 + cd src + msbuild /t:Rebuild /m /p:Configuration=%BUILD_TYPE% /p:BuildInParallel=true /p:Platform="Any CPU" + cd .. +) \ No newline at end of file diff --git a/pictures/findwindow.png b/pictures/findwindow.png new file mode 100644 index 0000000..be0ba38 Binary files /dev/null and b/pictures/findwindow.png differ diff --git a/pictures/mainwindow.png b/pictures/mainwindow.png new file mode 100644 index 0000000..a53edd0 Binary files /dev/null and b/pictures/mainwindow.png differ diff --git a/pictures/networkwindow.png b/pictures/networkwindow.png new file mode 100644 index 0000000..e385838 Binary files /dev/null and b/pictures/networkwindow.png differ diff --git a/src/Windows.RegistryEditor.sln b/src/Windows.RegistryEditor.sln new file mode 100644 index 0000000..4fe0cbd --- /dev/null +++ b/src/Windows.RegistryEditor.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2047 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryEditor", "Windows.RegistryEditor\RegistryEditor.csproj", "{E76E123C-04A1-488F-AA28-A5FF6FE236E5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E76E123C-04A1-488F-AA28-A5FF6FE236E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E76E123C-04A1-488F-AA28-A5FF6FE236E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E76E123C-04A1-488F-AA28-A5FF6FE236E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E76E123C-04A1-488F-AA28-A5FF6FE236E5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F377F101-355E-4E65-B5F2-8A0F71D97308} + EndGlobalSection +EndGlobal diff --git a/src/Windows.RegistryEditor/App.config b/src/Windows.RegistryEditor/App.config new file mode 100644 index 0000000..016d28f --- /dev/null +++ b/src/Windows.RegistryEditor/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/FindResultsArgs.cs b/src/Windows.RegistryEditor/Events/FindResultsArgs.cs new file mode 100644 index 0000000..ba5b301 --- /dev/null +++ b/src/Windows.RegistryEditor/Events/FindResultsArgs.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Windows.RegistryEditor.Events +{ + public class FindResultsArgs : EventArgs + { + public List Matches { get; set; } + + public FindResultsArgs(List matches) + { + Matches = matches; + } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/FindSingleResultArgs.cs b/src/Windows.RegistryEditor/Events/FindSingleResultArgs.cs new file mode 100644 index 0000000..a065079 --- /dev/null +++ b/src/Windows.RegistryEditor/Events/FindSingleResultArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Windows.RegistryEditor.Events +{ + public class FindSingleResultArgs : EventArgs + { + public string Match { get; set; } + + public FindSingleResultArgs(string match) + { + Match = match; + } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/ProgressArgs.cs b/src/Windows.RegistryEditor/Events/ProgressArgs.cs new file mode 100644 index 0000000..ca65603 --- /dev/null +++ b/src/Windows.RegistryEditor/Events/ProgressArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Windows.RegistryEditor.Events +{ + public class ProgressArgs : EventArgs + { + public string Message { get; set; } + + public ProgressArgs(string message) + { + Message = message; + } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/ProgressChangedArgs.cs b/src/Windows.RegistryEditor/Events/ProgressChangedArgs.cs new file mode 100644 index 0000000..b06e56a --- /dev/null +++ b/src/Windows.RegistryEditor/Events/ProgressChangedArgs.cs @@ -0,0 +1,12 @@ +namespace Windows.RegistryEditor.Events +{ + public class ProgressChangedArgs : ProgressArgs + { + public string Hive { get; set; } + public ProgressChangedArgs(string message, string hive) + : base(message) + { + Hive = hive; + } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/ProgressFinishedArgs.cs b/src/Windows.RegistryEditor/Events/ProgressFinishedArgs.cs new file mode 100644 index 0000000..3ffebef --- /dev/null +++ b/src/Windows.RegistryEditor/Events/ProgressFinishedArgs.cs @@ -0,0 +1,9 @@ +namespace Windows.RegistryEditor.Events +{ + public class ProgressFinishedArgs : ProgressArgs + { + public ProgressFinishedArgs(string message) + : base(message) + { } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Events/ProgressStartedArgs.cs b/src/Windows.RegistryEditor/Events/ProgressStartedArgs.cs new file mode 100644 index 0000000..c6c8198 --- /dev/null +++ b/src/Windows.RegistryEditor/Events/ProgressStartedArgs.cs @@ -0,0 +1,12 @@ +namespace Windows.RegistryEditor.Events +{ + public class ProgressStartedArgs : ProgressArgs + { + public string Hive { get; set; } + public ProgressStartedArgs(string message, string hive) + : base(message) + { + Hive = hive; + } + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Program.cs b/src/Windows.RegistryEditor/Program.cs new file mode 100644 index 0000000..226cea4 --- /dev/null +++ b/src/Windows.RegistryEditor/Program.cs @@ -0,0 +1,17 @@ +using System; +using System.Windows.Forms; +using Windows.RegistryEditor.Views; + +namespace Windows.RegistryEditor +{ + static class Program + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainWindow()); + } + } +} diff --git a/src/Windows.RegistryEditor/Properties/AssemblyInfo.cs b/src/Windows.RegistryEditor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8fa65ea --- /dev/null +++ b/src/Windows.RegistryEditor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Registry Editor")] +[assembly: AssemblyDescription("Windows utility to help scanning and removing unwanted registries.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Registry Editor")] +[assembly: AssemblyCopyright("Copyright © 2018 Reich")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e76e123c-04a1-488f-aa28-a5ff6fe236e5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.1")] +[assembly: AssemblyFileVersion("1.0.1")] diff --git a/src/Windows.RegistryEditor/Properties/Resources.Designer.cs b/src/Windows.RegistryEditor/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8d07252 --- /dev/null +++ b/src/Windows.RegistryEditor/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// 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 Windows.RegistryEditor.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", "15.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("Windows.RegistryEditor.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 resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon app { + get { + object obj = ResourceManager.GetObject("app", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap loader_clock { + get { + object obj = ResourceManager.GetObject("loader_clock", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/src/Windows.RegistryEditor/Properties/Resources.resx b/src/Windows.RegistryEditor/Properties/Resources.resx new file mode 100644 index 0000000..e7f7c3b --- /dev/null +++ b/src/Windows.RegistryEditor/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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\app.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\loader_clock.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Properties/Settings.Designer.cs b/src/Windows.RegistryEditor/Properties/Settings.Designer.cs new file mode 100644 index 0000000..1a848bd --- /dev/null +++ b/src/Windows.RegistryEditor/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// 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 Windows.RegistryEditor.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/src/Windows.RegistryEditor/Properties/Settings.settings b/src/Windows.RegistryEditor/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/src/Windows.RegistryEditor/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Windows.RegistryEditor/RegistryEditor.csproj b/src/Windows.RegistryEditor/RegistryEditor.csproj new file mode 100644 index 0000000..9e97f2f --- /dev/null +++ b/src/Windows.RegistryEditor/RegistryEditor.csproj @@ -0,0 +1,132 @@ + + + + + Debug + AnyCPU + {E76E123C-04A1-488F-AA28-A5FF6FE236E5} + WinExe + Windows.RegistryEditor + RegistryEditor-v1.0.1 + v4.7 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + app.manifest + + + Resources/app.ico + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + NetworkWindow.cs + + + UserControl + + + CheckBoxes.cs + + + Component + + + UserControl + + + Loader.cs + + + + Form + + + FindWindow.cs + + + Form + + + MainWindow.cs + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Resources/app.ico b/src/Windows.RegistryEditor/Resources/app.ico new file mode 100644 index 0000000..869c96d Binary files /dev/null and b/src/Windows.RegistryEditor/Resources/app.ico differ diff --git a/src/Windows.RegistryEditor/Resources/loader_clock.gif b/src/Windows.RegistryEditor/Resources/loader_clock.gif new file mode 100644 index 0000000..031c908 Binary files /dev/null and b/src/Windows.RegistryEditor/Resources/loader_clock.gif differ diff --git a/src/Windows.RegistryEditor/Utils/Native/NativeListViewItem.cs b/src/Windows.RegistryEditor/Utils/Native/NativeListViewItem.cs new file mode 100644 index 0000000..4816079 --- /dev/null +++ b/src/Windows.RegistryEditor/Utils/Native/NativeListViewItem.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices; + +namespace Windows.RegistryEditor.Utils.Native +{ + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal struct NativeListViewItem + { + public int mask; + public int iItem; + public int iSubItem; + public int state; + public int stateMask; + [MarshalAs(UnmanagedType.LPTStr)] + public string pszText; + public int cchTextMax; + public int iImage; + public IntPtr lParam; + public int iIndent; + public int iGroupId; + public int cColumns; + public IntPtr puColumns; + } +} diff --git a/src/Windows.RegistryEditor/Utils/Native/NativeMethods.cs b/src/Windows.RegistryEditor/Utils/Native/NativeMethods.cs new file mode 100644 index 0000000..2428f73 --- /dev/null +++ b/src/Windows.RegistryEditor/Utils/Native/NativeMethods.cs @@ -0,0 +1,28 @@ +using System; +using System.Runtime.InteropServices; +using System.Security; +using System.Windows.Forms; + +namespace Windows.RegistryEditor.Utils.Native +{ + [ComVisible(false), SuppressUnmanagedCodeSecurity] + internal sealed class NativeMethods + { + + #region --- ListView WinForms Control Stuff --- + + private const int LVM_FIRST = 0x1000; + private const int LVM_SETITEMSTATE = LVM_FIRST + 43; + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref NativeListViewItem lvi); + + internal static void SetItemState(ListView listView, int itemIndex, int mask, int value) + { + NativeListViewItem lvItem = new NativeListViewItem {stateMask = mask, state = value}; + SendMessage(listView.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem); + } + + #endregion #region --- ListView Functions --- + } +} diff --git a/src/Windows.RegistryEditor/Utils/RegistryUtils.cs b/src/Windows.RegistryEditor/Utils/RegistryUtils.cs new file mode 100644 index 0000000..0dd471a --- /dev/null +++ b/src/Windows.RegistryEditor/Utils/RegistryUtils.cs @@ -0,0 +1,126 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; + +namespace Windows.RegistryEditor.Utils +{ + public static class RegistryUtils + { + public const string HKCR = "HKEY_CLASSES_ROOT"; + public const string HKCU = "HKEY_CURRENT_USER"; + public const string HKLM = "HKEY_LOCAL_MACHINE"; + public const string HKU = "HKEY_USERS"; + public const string HKCC = "HKEY_CURRENT_CONFIG"; + + public const string SHKCR = "HKCR"; + public const string SHKCU = "HKCU"; + public const string SHKLM = "HKLM"; + public const string SHKU = "HKU"; + public const string SHKCC = "HKCC"; + + public const string REG_SZ = "REG_SZ"; + public const string REG_EXPAND_SZ = "REG_EXPAND_SZ"; + public const string REG_MULTI_SZ = "REG_MULTI_SZ"; + public const string REG_DWORD = "REG_DWORD"; + public const string REG_QWORD = "REG_QWORD"; + public const string REG_DWORD_LITTLE_ENDIAN = "REG_DWORD_LITTLE_ENDIAN"; + public const string REG_QWORD_LITTLE_ENDIAN = "REG_QWORD_LITTLE_ENDIAN"; + public const string REG_DWORD_BIG_ENDIAN = "REG_DWORD_BIG_ENDIAN"; + public const string REG_BINARY = "REG_BINARY"; + public const string REG_NONE = "REG_NONE"; + public const string REG_LINK = "REG_LINK"; + public const string REG_RESOURCE_LIST = "REG_RESOURCE_LIST"; + + private const string HKEY_REGEDIT = @"HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit"; + + public static void OpenRegistryLocation(string path) + { + string args = $"{HKEY_REGEDIT} /v LastKey /t REG_SZ /d \"{path}\" /f"; + ProcessStartInfo procInfo = new ProcessStartInfo + { + FileName = "REG", + Arguments = $"ADD {args}", + CreateNoWindow = true, + UseShellExecute = false + }; + + Process.Start(procInfo); + + Utility.KillProcess("regedit"); + Process.Start("regedit.exe"); + } + + public static void ExportHive(string hivePath, string dstDir) + { + if (!Directory.Exists(dstDir)) + Directory.CreateDirectory(dstDir); + + string fileName = Utility.ValidateDirOrFileName(hivePath.Split('\\').Last()); + string dstFile = Path.Combine(dstDir, fileName + ".reg"); + ProcessStartInfo procInfo = new ProcessStartInfo() + { + FileName = "REG", + Arguments = $"EXPORT \"{hivePath}\" \"{dstFile}\" /y", + CreateNoWindow = true, + UseShellExecute = false + }; + + Process.Start(procInfo); + } + + public static void DeleteHive(string hivePath) + { + ProcessStartInfo procInfo = new ProcessStartInfo() + { + FileName = "REG", + Arguments = $"DELETE \"{hivePath}\" /f", + CreateNoWindow = true, + UseShellExecute = false + }; + + Process.Start(procInfo); + } + + public static string GetHiveShortcut(string hive) + { + switch (hive) + { + case HKCR: return SHKCR; + case HKCU: return SHKCU; + case HKLM: return SHKLM; + case HKU: return SHKU; + case HKCC: return SHKCC; + + default: + throw new ArgumentException($"[GetHiveShortcut] - Invalid HKEY input -> {hive}"); + } + } + + public static string GetHiveFullName(string hive) + { + switch (hive) + { + case SHKCR: return HKCR; + case SHKCU: return HKCU; + case SHKLM: return HKLM; + case SHKU: return HKU; + case SHKCC: return HKCC; + + default: + throw new ArgumentException($"[GetHiveFullName] - Invalid HKEY input -> {hive}"); + } + } + + public static string GetRemoteShortcut(string hive) + { + return GetHiveShortcut(hive.Split('\\').Last()); + } + + public static string GetRemoteHiveFullName(string hive) + { + return GetHiveFullName(hive.Split('\\').Last()); + } + + } +} diff --git a/src/Windows.RegistryEditor/Utils/Stopwatch.cs b/src/Windows.RegistryEditor/Utils/Stopwatch.cs new file mode 100644 index 0000000..7a3badc --- /dev/null +++ b/src/Windows.RegistryEditor/Utils/Stopwatch.cs @@ -0,0 +1,48 @@ +using System; + +using SW = System.Diagnostics.Stopwatch; + +namespace Windows.RegistryEditor.Utils +{ + public class Stopwatch + { + public event Action Started; + public event Action Stopped; + + protected virtual void OnStarted() => Started?.Invoke(); + protected virtual void OnStopped(TimeSpan e) => Stopped?.Invoke(e); + + + private SW watch; + + public Stopwatch() + { + watch = new SW(); + } + + public TimeSpan Elapsed => watch.Elapsed; + + public bool IsRunning => watch.IsRunning; + + public Stopwatch Start(bool reset = false) + { + if (reset) watch.Reset(); + + watch.Start(); + OnStarted(); + + return this; + } + + public TimeSpan Stop() + { + if (!watch.IsRunning) + throw new InvalidOperationException("Stopwatch isn't running"); + + watch.Stop(); + OnStopped(Elapsed); + + return Elapsed; + } + } +} diff --git a/src/Windows.RegistryEditor/Utils/Utility.cs b/src/Windows.RegistryEditor/Utils/Utility.cs new file mode 100644 index 0000000..c9484b8 --- /dev/null +++ b/src/Windows.RegistryEditor/Utils/Utility.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Windows.RegistryEditor.Utils.Native; + +namespace Windows.RegistryEditor.Utils +{ + public static class Utility + { + + public static void InvokeSafe(this ISynchronizeInvoke caller, Action method) + { + if (caller.InvokeRequired) + caller.Invoke(method, null); + else + method.Invoke(); + } + + public static T InvokeSafe(this ISynchronizeInvoke caller, Func method) + { + if (caller.InvokeRequired) + return (T)caller.Invoke(method, null); + + return method.Invoke(); + } + + public static void BeginInvokeSafe(this ISynchronizeInvoke caller, Action method) + { + if (caller.InvokeRequired) + caller.BeginInvoke(method, null); + else + method.Invoke(); + } + + public static bool KillProcess(string proc) + { + foreach (Process process in Process.GetProcesses()) + { + if (process.ProcessName.ToLower() != proc) continue; + + process.Kill(); + return true; + } + + return false; + } + + /// + /// Characters that are not allowed on windows: + /// < > : " / \ | ? + /// + public static string ValidateDirOrFileName(string name) + { + return Regex.Replace(name, "<|>|:|\"|/|\\\\|\\||\\?|\\*", " "); + } + + public static void SelectAllItems(this ListView listView) + { + NativeMethods.SetItemState(listView, -1, 2, 2); + } + + public static void DeselectAllItems(this ListView listView) + { + NativeMethods.SetItemState(listView, -1, 2, 0); + } + + public static void OpenFolderInExplorer(string path) + { + Process.Start("explorer.exe", path); + } + } +} diff --git a/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.Designer.cs b/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.Designer.cs new file mode 100644 index 0000000..bf4b7dc --- /dev/null +++ b/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.Designer.cs @@ -0,0 +1,95 @@ +namespace Windows.RegistryEditor.Views.Controls +{ + partial class CheckBoxes + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lbxAll = new System.Windows.Forms.CheckedListBox(); + this.cbxAll = new System.Windows.Forms.CheckBox(); + this.panelMain = new System.Windows.Forms.TableLayoutPanel(); + this.panelMain.SuspendLayout(); + this.SuspendLayout(); + // + // lbxAll + // + this.lbxAll.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbxAll.FormattingEnabled = true; + this.lbxAll.Location = new System.Drawing.Point(0, 30); + this.lbxAll.Margin = new System.Windows.Forms.Padding(0); + this.lbxAll.Name = "lbxAll"; + this.lbxAll.Size = new System.Drawing.Size(148, 90); + this.lbxAll.TabIndex = 0; + this.lbxAll.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.LbxAll_ItemCheck); + // + // cbxAll + // + this.cbxAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxAll.AutoSize = true; + this.cbxAll.Location = new System.Drawing.Point(3, 10); + this.cbxAll.Name = "cbxAll"; + this.cbxAll.Size = new System.Drawing.Size(70, 17); + this.cbxAll.TabIndex = 1; + this.cbxAll.Text = "Select All"; + this.cbxAll.UseVisualStyleBackColor = true; + this.cbxAll.CheckedChanged += new System.EventHandler(this.CbxAll_CheckedChanged); + // + // panelMain + // + this.panelMain.ColumnCount = 1; + this.panelMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.panelMain.Controls.Add(this.cbxAll, 0, 0); + this.panelMain.Controls.Add(this.lbxAll, 0, 1); + this.panelMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelMain.Location = new System.Drawing.Point(0, 0); + this.panelMain.Name = "panelMain"; + this.panelMain.RowCount = 2; + this.panelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F)); + this.panelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.panelMain.Size = new System.Drawing.Size(148, 120); + this.panelMain.TabIndex = 2; + // + // CheckBoxes + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panelMain); + this.Name = "CheckBoxes"; + this.Size = new System.Drawing.Size(148, 120); + this.Load += new System.EventHandler(this.CheckBoxes_Load); + this.panelMain.ResumeLayout(false); + this.panelMain.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.CheckedListBox lbxAll; + private System.Windows.Forms.CheckBox cbxAll; + private System.Windows.Forms.TableLayoutPanel panelMain; + } +} diff --git a/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.cs b/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.cs new file mode 100644 index 0000000..d81cc93 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/Controls/CheckBoxes.cs @@ -0,0 +1,221 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; +using System.Management.Instrumentation; +using System.Reflection; +using System.Windows.Forms; + +namespace Windows.RegistryEditor.Views.Controls +{ + public partial class CheckBoxes : UserControl + { + + public event ItemCheckEventHandler ItemCheck; + public event EventHandler SelectAllCheckedChanged; + + protected virtual void OnItemCheck(ItemCheckEventArgs e) => ItemCheck?.Invoke(this, e); + protected virtual void OnSelectAllCheckedChanged() => SelectAllCheckedChanged?.Invoke(this, EventArgs.Empty); + + public CheckBoxes() + { + InitializeComponent(); + CheckOnClick = true; + lbxAll.Dock = DockStyle.Fill; + + foreach (Control control in panelMain.Controls) + typeof(Control).InvokeMember("DoubleBuffered", + BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, + null, control, new object[] { true }); + } + + private void CheckBoxes_Load(object sender, EventArgs e) + { + + } + + private void CbxAll_CheckedChanged(object sender, EventArgs e) + { + for (int i = 0; i < lbxAll.Items.Count; i++) + { + lbxAll.SetItemChecked(i, cbxAll.Checked); + } + + OnSelectAllCheckedChanged(); + } + + private void LbxAll_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (e.NewValue == CheckState.Unchecked) + { + cbxAll.CheckedChanged -= CbxAll_CheckedChanged; + cbxAll.Checked = false; + cbxAll.CheckedChanged += CbxAll_CheckedChanged; + } + else if (lbxAll.Items.Count == lbxAll.CheckedItems.Count + 1 + && e.NewValue == CheckState.Checked) + { + cbxAll.CheckedChanged -= CbxAll_CheckedChanged; + cbxAll.Checked = true; + cbxAll.CheckedChanged += CbxAll_CheckedChanged; + } + + OnItemCheck(e); + } + + [Browsable(false)] + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED + return cp; + } + } + + [MergableProperty(false)] + [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Localizable(true)] + [Category("Data")] + [Description("Gets the collection of items in this CheckedListBox.")] + public CheckedListBox.ObjectCollection Items + { + get + { + CbxAll_CheckedChanged(null, null); // When new items are added through the designer, check the state of the cbxAll. + return lbxAll.Items; + } + } + + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + [Description("CheckedListBox DataSource.")] + public object DataSource + { + get => lbxAll.DataSource; + set => lbxAll.DataSource = value; + } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Deprecated", false)] + public new Image BackgroundImage { get; set; } + + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public new ImageLayout BackgroundImageLayout { get; set; } + + public new Color BackColor + { + get => lbxAll.BackColor; + set => UpdateControl(() => lbxAll.BackColor = value); + } + + public new BorderStyle BorderStyle + { + get => lbxAll.BorderStyle; + set => UpdateControl(() => lbxAll.BorderStyle = value); + } + + public new Color ForeColor + { + get => lbxAll.ForeColor; + set => UpdateControl(() => lbxAll.ForeColor = value); + } + + [Category("Appearance")] + [Description("Indicates if the CheckBoxes should show up as flat or 3D in appearance.")] + public bool ThreeDCheckBoxes + { + get => lbxAll.ThreeDCheckBoxes; + set => UpdateControl(() => lbxAll.ThreeDCheckBoxes = value); + } + + [Category("Behavior")] + [Description("Indicates if the check box should be toggled with the first click on an item.")] + public bool CheckOnClick + { + get => lbxAll.CheckOnClick; + set => lbxAll.CheckOnClick = value; + } + + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + [Description("Collection of checked items in this CheckedListBox.")] + public CheckedListBox.CheckedItemCollection CheckedItems => lbxAll.CheckedItems; + + [Browsable(true)] + [Description("Indicates if all check boxes are checked in the CheckedListBox.")] + [Category("Appearance")] + public bool SelectAllChecked + { + get => cbxAll.Checked; + set => UpdateControl(() => cbxAll.Checked = value); + } + + public void UpdateControl(Action action) + { + action.Invoke(); + if (DesignMode) Invalidate(); + } + + /// + /// Sets the checked value of the given item. This value should be a boolean. + /// + public void SetItemChecked(int index, bool value) + { + lbxAll.SetItemChecked(index, value); + } + + /// + /// Sets the checked value of the given item. This value should be from + /// the System.Windows.Forms.CheckState enumeration. + /// + public void SetItemCheckState(int index, CheckState value) + { + lbxAll.SetItemCheckState(index, value); + } + + /// + /// Indicates if the given item is, in any way, shape, or form, checked. + /// This will return true if the item is fully or indeterminately checked. + /// + public bool GetItemChecked(int index) + { + return lbxAll.GetItemChecked(index); + } + + /// + /// Gets the check value of the current item. This value will be from the + /// System.Windows.Forms.CheckState enumeration. + /// + public CheckState GetItemCheckState(int index) + { + return lbxAll.GetItemCheckState(index); + } + + public void SetItemCheckedByName(string value, bool flag) + { + for (int i = 0; i < lbxAll.Items.Count; i++) + { + if (lbxAll.Items[i].ToString().Equals(value)) + lbxAll.SetItemChecked(i, flag); + } + + throw new InstanceNotFoundException($"[SetItemCheckedByName] - Couldn't find the specified value -> {value}."); + } + + public bool GetItemCheckedByName(string value) + { + for (int i = 0; i < lbxAll.Items.Count; i++) + { + if (lbxAll.Items[i].ToString().Equals(value)) + return lbxAll.GetItemChecked(i); + } + + throw new InstanceNotFoundException($"[GetItemCheckedByName] - Couldn't find the specified value -> {value}."); + } + + } +} diff --git a/src/Windows.RegistryEditor/Views/Controls/ListViewEx.cs b/src/Windows.RegistryEditor/Views/Controls/ListViewEx.cs new file mode 100644 index 0000000..a1fbc31 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/Controls/ListViewEx.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using Windows.RegistryEditor.Utils; + +namespace Windows.RegistryEditor.Views.Controls +{ + public class ListViewEx : ListView + { + + public ListViewEx() + { + CheckBoxes = true; + FullRowSelect = true; + GridLines = true; + } + + public void SelectAllItems() => Utility.SelectAllItems(this); + + public void DeselectAllItems() => Utility.DeselectAllItems(this); + + public void CheckAllItems(bool value) + { + foreach (ListViewItem item in Items) + item.Checked = value; + } + + public string GetAllSelectedSubItemsText(int index) + { + string data = String.Empty; + foreach (ListViewItem item in SelectedItems) + data += item.SubItems[index].Text + Environment.NewLine; + + data = data.TrimEnd(); + + return data; + } + + public List GetAllSelectedSubItemsTextList(int index) + { + List newList = new List(); + foreach (ListViewItem item in SelectedItems) + newList.Add(item.SubItems[index].Text); + + return newList; + } + + public List GetAllCheckedSubItemsTextList(int index) + { + List newList = new List(); + foreach (ListViewItem item in CheckedItems) + newList.Add(item.SubItems[index].Text); + + return newList; + } + } +} diff --git a/src/Windows.RegistryEditor/Views/Controls/Loader.Designer.cs b/src/Windows.RegistryEditor/Views/Controls/Loader.Designer.cs new file mode 100644 index 0000000..81194d1 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/Controls/Loader.Designer.cs @@ -0,0 +1,64 @@ +namespace Windows.RegistryEditor.Views.Controls +{ + partial class Loader + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pbxGif = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pbxGif)).BeginInit(); + this.SuspendLayout(); + // + // pbxGif + // + this.pbxGif.Dock = System.Windows.Forms.DockStyle.Fill; + this.pbxGif.Image = global::Windows.RegistryEditor.Properties.Resources.loader_clock; + this.pbxGif.Location = new System.Drawing.Point(0, 0); + this.pbxGif.Name = "pbxGif"; + this.pbxGif.Size = new System.Drawing.Size(100, 100); + this.pbxGif.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pbxGif.TabIndex = 0; + this.pbxGif.TabStop = false; + // + // Loader + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Transparent; + this.Controls.Add(this.pbxGif); + this.Name = "Loader"; + this.Size = new System.Drawing.Size(100, 100); + this.Load += new System.EventHandler(this.Spinner_Load); + ((System.ComponentModel.ISupportInitialize)(this.pbxGif)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.PictureBox pbxGif; + } +} diff --git a/src/Windows.RegistryEditor/Views/Controls/Loader.cs b/src/Windows.RegistryEditor/Views/Controls/Loader.cs new file mode 100644 index 0000000..ad3369f --- /dev/null +++ b/src/Windows.RegistryEditor/Views/Controls/Loader.cs @@ -0,0 +1,208 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Runtime.CompilerServices; +using System.Windows.Forms; +using Windows.RegistryEditor.Properties; + +namespace Windows.RegistryEditor.Views.Controls +{ + public enum LoaderKind + { + Clock, + Arrows, + CircleBall, + Loading, + Snake, + WheelThrobber + } + + public partial class Loader : UserControl + { + #region --- Fields --- + + private LoaderKind loaderKind; + + #endregion --- Fields --- + + + + #region --- Properties --- + + [Description("Whether to disable all controls on form when loader is displayed.")] + [Category("Behavior")] + public bool DisableControlsOnWork { get; set; } + + [Description("The size of the control when it's spinning. The purpose of this property is " + + "to allow you hidding your loader as a very small size in the corner, while " + + "being able to specifying the expected size.")] + [Category("Layout")] + public Size SizeLoading { get; set; } + + [Description("Gets or sets the loader appearance to be displayed.")] + [Category("Appearance")] + public LoaderKind LoaderKind + { + get => loaderKind; + set + { + if (value == loaderKind) return; + + loaderKind = value; + pbxGif.Image = CreateLoaderImage(value); + if (DesignMode) Invalidate(); + } + } + + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ExStyle |= 0x02000000; // Turns on WS_EX_COMPOSITED + return cp; + } + } + + #endregion --- Properties --- + + + public Loader() + { + SetStyle(ControlStyles.SupportsTransparentBackColor | + ControlStyles.UserPaint | + ControlStyles.ResizeRedraw | + ControlStyles.Selectable, true); + + InitializeComponent(); + + DoubleBuffered = true; + Visible = false; + DisableControlsOnWork = true; + SizeLoading = new Size(100, 100); + LoaderKind = LoaderKind.Clock; + } + + private void Spinner_Load(object sender, EventArgs e) + { + if (IsParentNull()) return; + + ParentForm.SizeChanged += delegate { PositionToParent(); }; + } + + private void PositionToParent() + { + if (IsParentNull()) return; + + this.Invoke(new Action(() => Left = (ParentForm.ClientSize.Width - Width) / 2)); + this.Invoke(new Action(() => Top = (ParentForm.ClientSize.Height - Height) / 2)); + } + + public new void Show() + { + if (IsParentNull() || Visible) return; + + this.Invoke(new Action(() => Size = SizeLoading)); + + if (DisableControlsOnWork) + EnableParentControls(false); + + PositionToParent(); + + this.Invoke(new Action(() => base.Show())); + this.Invoke(new Action(() => BringToFront())); + } + + public new void Hide() + { + if (IsParentNull() || !Visible) return; + + if (DisableControlsOnWork) + EnableParentControls(true); + + this.Invoke(new Action(() => base.Hide())); + this.Invoke(new Action(() => SendToBack())); + } + + + private bool IsParentNull([CallerMemberName] string callerMethod = "") + { + bool isNull = ParentForm == null; + + if (isNull) + Debug.WriteLine($"[{callerMethod}] - Parent cannot be null."); + + return isNull; + } + private void EnableParentControls(bool enabled) + { + if (IsParentNull()) return; + + foreach (Control control in ParentForm.Controls) + { + if (control.GetType() == typeof(Loader)) continue; + + control.Invoke(new Action(() => control.Enabled = enabled)); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + Transparent(this, e.Graphics); + base.OnPaint(e); + } + + public static void Transparent(Control control, Graphics graphics) + { + Control owner = control.Parent; + if (owner == null) return; + + Rectangle controlBounds = control.Bounds; + ControlCollection ownerControls = owner.Controls; + int controlIndex = ownerControls.IndexOf(control); + Bitmap bitmapBehind = null; + for (int i = controlIndex + 1; i < ownerControls.Count; i++) + { + Control targetControl = ownerControls[i]; + if (!targetControl.Bounds.IntersectsWith(controlBounds)) continue; + + if (bitmapBehind == null) + bitmapBehind = new Bitmap(control.Parent.ClientSize.Width, control.Parent.ClientSize.Height); + targetControl.DrawToBitmap(bitmapBehind, targetControl.Bounds); + } + + if (bitmapBehind == null) return; + + graphics.DrawImage(bitmapBehind, control.ClientRectangle, controlBounds, GraphicsUnit.Pixel); + bitmapBehind.Dispose(); + } + + private Image CreateLoaderImage(LoaderKind value) + { + switch (value) + { + case LoaderKind.Clock: + return Resources.loader_clock; + + //case LoaderKind.Arrows: + // return Resources.loader_arrows; + + //case LoaderKind.CircleBall: + // return Resources.loader_circleball; + + //case LoaderKind.Loading: + // return Resources.loader_loading; + + //case LoaderKind.Snake: + // return Resources.loader_snake; + + //case LoaderKind.WheelThrobber: + // return Resources.loader_wheelthrobber; + + default: + throw new ArgumentOutOfRangeException(nameof(value), value, null); + } + } + } +} diff --git a/src/Windows.RegistryEditor/Views/FindWindow.Designer.cs b/src/Windows.RegistryEditor/Views/FindWindow.Designer.cs new file mode 100644 index 0000000..bf52dda --- /dev/null +++ b/src/Windows.RegistryEditor/Views/FindWindow.Designer.cs @@ -0,0 +1,405 @@ +namespace Windows.RegistryEditor.Views +{ + partial class FindWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.tbxSearch = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.gbxLookAt = new System.Windows.Forms.GroupBox(); + this.cbxData = new System.Windows.Forms.CheckBox(); + this.cbxValues = new System.Windows.Forms.CheckBox(); + this.cbxKeys = new System.Windows.Forms.CheckBox(); + this.cbxMatchString = new System.Windows.Forms.CheckBox(); + this.btnFindNext = new System.Windows.Forms.Button(); + this.btnFindAll = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.cbxCaseSensitive = new System.Windows.Forms.CheckBox(); + this.cbxRegularEx = new System.Windows.Forms.CheckBox(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.gbxOptions = new System.Windows.Forms.GroupBox(); + this.gbxHkeys = new System.Windows.Forms.GroupBox(); + this.cbxsHkeys = new Windows.RegistryEditor.Views.Controls.CheckBoxes(); + this.gbxDataTypes = new System.Windows.Forms.GroupBox(); + this.cbxsDataTypes = new Windows.RegistryEditor.Views.Controls.CheckBoxes(); + this.tbxRemoteComputer = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.cbxRemoteSearch = new System.Windows.Forms.CheckBox(); + this.btnFindAvailableMachines = new System.Windows.Forms.Button(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.loader = new Windows.RegistryEditor.Views.Controls.Loader(); + this.gbxLookAt.SuspendLayout(); + this.gbxOptions.SuspendLayout(); + this.gbxHkeys.SuspendLayout(); + this.gbxDataTypes.SuspendLayout(); + this.SuspendLayout(); + // + // tbxSearch + // + this.tbxSearch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbxSearch.Location = new System.Drawing.Point(110, 57); + this.tbxSearch.Name = "tbxSearch"; + this.tbxSearch.Size = new System.Drawing.Size(454, 20); + this.tbxSearch.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(44, 60); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(60, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Find String:"; + // + // gbxLookAt + // + this.gbxLookAt.Controls.Add(this.cbxData); + this.gbxLookAt.Controls.Add(this.cbxValues); + this.gbxLookAt.Controls.Add(this.cbxKeys); + this.gbxLookAt.Location = new System.Drawing.Point(18, 83); + this.gbxLookAt.Name = "gbxLookAt"; + this.gbxLookAt.Size = new System.Drawing.Size(86, 120); + this.gbxLookAt.TabIndex = 4; + this.gbxLookAt.TabStop = false; + this.gbxLookAt.Text = "Look at"; + // + // cbxData + // + this.cbxData.AutoSize = true; + this.cbxData.Checked = true; + this.cbxData.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxData.Location = new System.Drawing.Point(7, 66); + this.cbxData.Name = "cbxData"; + this.cbxData.Size = new System.Drawing.Size(49, 17); + this.cbxData.TabIndex = 2; + this.cbxData.Text = "Data"; + this.cbxData.UseVisualStyleBackColor = true; + // + // cbxValues + // + this.cbxValues.AutoSize = true; + this.cbxValues.Checked = true; + this.cbxValues.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxValues.Location = new System.Drawing.Point(7, 43); + this.cbxValues.Name = "cbxValues"; + this.cbxValues.Size = new System.Drawing.Size(58, 17); + this.cbxValues.TabIndex = 1; + this.cbxValues.Text = "Values"; + this.cbxValues.UseVisualStyleBackColor = true; + // + // cbxKeys + // + this.cbxKeys.AutoSize = true; + this.cbxKeys.Checked = true; + this.cbxKeys.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxKeys.Location = new System.Drawing.Point(7, 20); + this.cbxKeys.Name = "cbxKeys"; + this.cbxKeys.Size = new System.Drawing.Size(49, 17); + this.cbxKeys.TabIndex = 0; + this.cbxKeys.Text = "Keys"; + this.cbxKeys.UseVisualStyleBackColor = true; + // + // cbxMatchString + // + this.cbxMatchString.AutoSize = true; + this.cbxMatchString.Location = new System.Drawing.Point(6, 43); + this.cbxMatchString.Name = "cbxMatchString"; + this.cbxMatchString.Size = new System.Drawing.Size(113, 17); + this.cbxMatchString.TabIndex = 1; + this.cbxMatchString.Text = "Match whole word"; + this.cbxMatchString.UseVisualStyleBackColor = true; + // + // btnFindNext + // + this.btnFindNext.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnFindNext.Enabled = false; + this.btnFindNext.Location = new System.Drawing.Point(519, 272); + this.btnFindNext.Name = "btnFindNext"; + this.btnFindNext.Size = new System.Drawing.Size(75, 23); + this.btnFindNext.TabIndex = 1; + this.btnFindNext.Text = "Find Next"; + this.btnFindNext.UseVisualStyleBackColor = true; + this.btnFindNext.Click += new System.EventHandler(this.BtnFindSingle_Click); + // + // btnFindAll + // + this.btnFindAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnFindAll.Location = new System.Drawing.Point(519, 301); + this.btnFindAll.Name = "btnFindAll"; + this.btnFindAll.Size = new System.Drawing.Size(75, 23); + this.btnFindAll.TabIndex = 2; + this.btnFindAll.Text = "Find All"; + this.btnFindAll.UseVisualStyleBackColor = true; + this.btnFindAll.Click += new System.EventHandler(this.BtnFindAll_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.Enabled = false; + this.btnCancel.Location = new System.Drawing.Point(519, 330); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.BtnCancel_Click); + // + // cbxCaseSensitive + // + this.cbxCaseSensitive.AutoSize = true; + this.cbxCaseSensitive.Location = new System.Drawing.Point(6, 20); + this.cbxCaseSensitive.Name = "cbxCaseSensitive"; + this.cbxCaseSensitive.Size = new System.Drawing.Size(96, 17); + this.cbxCaseSensitive.TabIndex = 0; + this.cbxCaseSensitive.Text = "Case Sensitive"; + this.cbxCaseSensitive.UseVisualStyleBackColor = true; + // + // cbxRegularEx + // + this.cbxRegularEx.AutoSize = true; + this.cbxRegularEx.Enabled = false; + this.cbxRegularEx.Location = new System.Drawing.Point(6, 66); + this.cbxRegularEx.Name = "cbxRegularEx"; + this.cbxRegularEx.Size = new System.Drawing.Size(117, 17); + this.cbxRegularEx.TabIndex = 2; + this.cbxRegularEx.Text = "Regular Expression"; + this.cbxRegularEx.UseVisualStyleBackColor = true; + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Enabled = false; + this.textBox1.Location = new System.Drawing.Point(6, 90); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(478, 20); + this.textBox1.TabIndex = 3; + // + // gbxOptions + // + this.gbxOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.gbxOptions.Controls.Add(this.cbxMatchString); + this.gbxOptions.Controls.Add(this.textBox1); + this.gbxOptions.Controls.Add(this.cbxRegularEx); + this.gbxOptions.Controls.Add(this.cbxCaseSensitive); + this.gbxOptions.Location = new System.Drawing.Point(110, 83); + this.gbxOptions.Name = "gbxOptions"; + this.gbxOptions.Size = new System.Drawing.Size(490, 120); + this.gbxOptions.TabIndex = 5; + this.gbxOptions.TabStop = false; + this.gbxOptions.Text = "Search Options"; + // + // gbxHkeys + // + this.gbxHkeys.Controls.Add(this.cbxsHkeys); + this.gbxHkeys.Location = new System.Drawing.Point(18, 210); + this.gbxHkeys.Name = "gbxHkeys"; + this.gbxHkeys.Size = new System.Drawing.Size(194, 147); + this.gbxHkeys.TabIndex = 6; + this.gbxHkeys.TabStop = false; + this.gbxHkeys.Text = "HKEYS"; + // + // cbxsHkeys + // + this.cbxsHkeys.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.cbxsHkeys.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.cbxsHkeys.CheckOnClick = true; + this.cbxsHkeys.DataSource = null; + this.cbxsHkeys.Items.AddRange(new object[] { + "HKEY_CLASSES_ROOT", + "HKEY_CURRENT_USER", + "HKEY_LOCAL_MACHINE", + "HKEY_USERS", + "HKEY_CURRENT_CONFIG"}); + this.cbxsHkeys.Location = new System.Drawing.Point(6, 16); + this.cbxsHkeys.Name = "cbxsHkeys"; + this.cbxsHkeys.SelectAllChecked = false; + this.cbxsHkeys.Size = new System.Drawing.Size(182, 125); + this.cbxsHkeys.TabIndex = 0; + this.cbxsHkeys.ThreeDCheckBoxes = false; + // + // gbxDataTypes + // + this.gbxDataTypes.Controls.Add(this.cbxsDataTypes); + this.gbxDataTypes.Location = new System.Drawing.Point(218, 210); + this.gbxDataTypes.Name = "gbxDataTypes"; + this.gbxDataTypes.Size = new System.Drawing.Size(269, 147); + this.gbxDataTypes.TabIndex = 7; + this.gbxDataTypes.TabStop = false; + this.gbxDataTypes.Text = "Data Types"; + // + // cbxsDataTypes + // + this.cbxsDataTypes.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.cbxsDataTypes.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.cbxsDataTypes.CheckOnClick = true; + this.cbxsDataTypes.DataSource = null; + this.cbxsDataTypes.Items.AddRange(new object[] { + "REG_SZ", + "REG_EXPAND_SZ", + "REG_MULTI_SZ", + "REG_DWORD", + "REG_QWORD", + "REG_DWORD_LITTLE_ENDIAN", + "REG_QWORD_LITTLE_ENDIAN", + "REG_DWORD_BIG_ENDIAN", + "REG_BINARY", + "REG_NONE", + "REG_LINK", + "REG_RESOURCE_LIST"}); + this.cbxsDataTypes.Location = new System.Drawing.Point(6, 16); + this.cbxsDataTypes.Name = "cbxsDataTypes"; + this.cbxsDataTypes.SelectAllChecked = true; + this.cbxsDataTypes.Size = new System.Drawing.Size(257, 125); + this.cbxsDataTypes.TabIndex = 0; + this.cbxsDataTypes.ThreeDCheckBoxes = false; + // + // tbxRemoteComputer + // + this.tbxRemoteComputer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbxRemoteComputer.Enabled = false; + this.tbxRemoteComputer.Location = new System.Drawing.Point(110, 31); + this.tbxRemoteComputer.Name = "tbxRemoteComputer"; + this.tbxRemoteComputer.Size = new System.Drawing.Size(454, 20); + this.tbxRemoteComputer.TabIndex = 0; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(18, 34); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(86, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Computer Name:"; + // + // cbxRemoteSearch + // + this.cbxRemoteSearch.AutoSize = true; + this.cbxRemoteSearch.Location = new System.Drawing.Point(18, 8); + this.cbxRemoteSearch.Name = "cbxRemoteSearch"; + this.cbxRemoteSearch.Size = new System.Drawing.Size(227, 17); + this.cbxRemoteSearch.TabIndex = 4; + this.cbxRemoteSearch.Text = "Search in remote computer on the network"; + this.cbxRemoteSearch.UseVisualStyleBackColor = true; + this.cbxRemoteSearch.CheckedChanged += new System.EventHandler(this.CbxSearchInRemote_CheckedChanged); + // + // btnFindAvailableMachines + // + this.btnFindAvailableMachines.Enabled = false; + this.btnFindAvailableMachines.Location = new System.Drawing.Point(570, 30); + this.btnFindAvailableMachines.Name = "btnFindAvailableMachines"; + this.btnFindAvailableMachines.Size = new System.Drawing.Size(24, 21); + this.btnFindAvailableMachines.TabIndex = 9; + this.btnFindAvailableMachines.Text = "..."; + this.toolTip.SetToolTip(this.btnFindAvailableMachines, "Find available machines on the network."); + this.btnFindAvailableMachines.UseVisualStyleBackColor = true; + this.btnFindAvailableMachines.Click += new System.EventHandler(this.BtnFindAvailableMachines_Click); + // + // loader + // + this.loader.BackColor = System.Drawing.Color.Transparent; + this.loader.DisableControlsOnWork = false; + this.loader.LoaderKind = Windows.RegistryEditor.Views.Controls.LoaderKind.Clock; + this.loader.Location = new System.Drawing.Point(554, 226); + this.loader.Name = "loader"; + this.loader.Size = new System.Drawing.Size(40, 40); + this.loader.SizeLoading = new System.Drawing.Size(100, 100); + this.loader.TabIndex = 8; + this.loader.Visible = false; + // + // FindWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(606, 365); + this.Controls.Add(this.btnFindAvailableMachines); + this.Controls.Add(this.cbxRemoteSearch); + this.Controls.Add(this.loader); + this.Controls.Add(this.gbxDataTypes); + this.Controls.Add(this.gbxHkeys); + this.Controls.Add(this.gbxOptions); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnFindAll); + this.Controls.Add(this.btnFindNext); + this.Controls.Add(this.gbxLookAt); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.tbxRemoteComputer); + this.Controls.Add(this.tbxSearch); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.KeyPreview = true; + this.Name = "FindWindow"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Find"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FindWindow_FormClosing); + this.Load += new System.EventHandler(this.FindWindow_Load); + this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.FindWindow_KeyPress); + this.gbxLookAt.ResumeLayout(false); + this.gbxLookAt.PerformLayout(); + this.gbxOptions.ResumeLayout(false); + this.gbxOptions.PerformLayout(); + this.gbxHkeys.ResumeLayout(false); + this.gbxDataTypes.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.TextBox tbxSearch; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox gbxLookAt; + private System.Windows.Forms.CheckBox cbxData; + private System.Windows.Forms.CheckBox cbxValues; + private System.Windows.Forms.CheckBox cbxKeys; + private System.Windows.Forms.CheckBox cbxMatchString; + private System.Windows.Forms.Button btnFindNext; + private System.Windows.Forms.Button btnFindAll; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.CheckBox cbxCaseSensitive; + private System.Windows.Forms.CheckBox cbxRegularEx; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.GroupBox gbxOptions; + private System.Windows.Forms.GroupBox gbxHkeys; + private System.Windows.Forms.GroupBox gbxDataTypes; + private Windows.RegistryEditor.Views.Controls.CheckBoxes cbxsDataTypes; + private Windows.RegistryEditor.Views.Controls.CheckBoxes cbxsHkeys; + private Windows.RegistryEditor.Views.Controls.Loader loader; + private System.Windows.Forms.TextBox tbxRemoteComputer; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox cbxRemoteSearch; + private System.Windows.Forms.Button btnFindAvailableMachines; + private System.Windows.Forms.ToolTip toolTip; + } +} + diff --git a/src/Windows.RegistryEditor/Views/FindWindow.cs b/src/Windows.RegistryEditor/Views/FindWindow.cs new file mode 100644 index 0000000..f9fbe6b --- /dev/null +++ b/src/Windows.RegistryEditor/Views/FindWindow.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Security.Principal; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Windows.RegistryEditor.Events; +using Windows.RegistryEditor.Utils; +using Stopwatch = Windows.RegistryEditor.Utils.Stopwatch; + +namespace Windows.RegistryEditor.Views +{ + /// + /// https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/reg-query + /// + public partial class FindWindow : Form + { + private NetworkWindow refNetworkWindow; + public NetworkWindow NetworkInstance + { + get + { + if (refNetworkWindow != null && !refNetworkWindow.IsDisposed) + { + refNetworkWindow.Activate(); + return refNetworkWindow; + } + refNetworkWindow = new NetworkWindow(); + refNetworkWindow.MachineSelected += (e) => tbxRemoteComputer.Text = e; + refNetworkWindow.FormClosing += delegate { tbxSearch.Focus(); }; + return refNetworkWindow; + } + } + + + private List procsList; + private int procsExecuted; + private bool searchInProgress; + + private AutoResetEvent procToken; + private CancellationTokenSource cancelSrc; + private CancellationToken cancelToken; + + public FindWindow() + { + InitializeComponent(); + } + + private void FindWindow_Load(object sender, EventArgs e) + { + cbxsHkeys.SetItemChecked(1, true); + } + + private void BtnFindAvailableMachines_Click(object sender, EventArgs e) + { + NetworkInstance.ShowDialog(this); + } + + private void BtnFindSingle_Click(object sender, EventArgs e) { } + + private async void BtnFindAll_Click(object sender, EventArgs e) + { + if (String.IsNullOrEmpty(tbxSearch.Text)) return; + + if (cbxRemoteSearch.Checked) + { + DialogResult answer = MessageBox.Show( + "Scanning registries through the network may take a while depending on the" + + "chosen filter. Are you sure you want to continue?", "INFO", + MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + if (answer != DialogResult.Yes) return; + } + + Started(); + List hives = GetHkeysFilters(); + procsList = GenerateRegQueryProcs(hives); + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + OnProgressStarted(this, new ProgressStartedArgs("Starting to search for registries...", hives.First())); + + searchInProgress = true; + await ExecuteProcs(procsList); + searchInProgress = false; + procToken.Set(); + + stopwatch.Stop(); + OnProgressFinished(this, new ProgressFinishedArgs("Finished searching for registries.")); + Stopped(); + + Activate(); + MessageBox.Show("Finished searching. Time Taken:\n" + stopwatch.Elapsed.ToString("g"), + "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void Started() + { + btnFindAll.Enabled = false; + btnCancel.Enabled = true; + loader.Show(); + + procsExecuted = 0; + procToken = new AutoResetEvent(false); + cancelSrc = new CancellationTokenSource(); + cancelToken = cancelSrc.Token; + } + + private void Stopped() + { + Text = "Find"; + btnFindAll.Enabled = true; + btnCancel.Enabled = false; + loader.Hide(); + } + + /// + /// BIG NOTE: When we search through the registry remotely, we can't really access HKCR, HKCU, HKCC but at the same time + /// we don't really need to, as they can be found under HKLM and HKU. In other words, they're just symbolic links. i.e: + /// ### HKEY_CLASSES_ROOT links to: ### + /// HKEY_CURRENT_USER\Software\Classes + /// HKEY_LOCAL_MACHINE\SOFTWARE\Classes + /// HKEY_USERS\{UserSID}\Software\Classes + /// HKEY_USERS\{UserSID}_Classes + /// + /// ### HKEY_CURRENT_USER links to: ### + /// HKEY_USERS\{UserSID} + /// + /// ### HKEY_CURRENT_CONFIG links to: ### + /// HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Hardware Profiles\0001 + /// HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Hardware Profiles\Current + /// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\0001 + /// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current + /// + /// Getting user SID: + /// WindowsIdentity.GetCurrent().User + /// whoami /user + /// + private List GetHkeysFilters() + { + List hives = new List(); + if (cbxRemoteSearch.Checked) + { + hives.Add(RegistryUtils.HKLM); + hives.Add(RegistryUtils.HKU); + #region experimental + //string userSID = WindowsIdentity.GetCurrent().User?.Value; + //Debug.Assert(userSID != null, "userSID != null"); + //foreach (string hive in cbxsHkeys.CheckedItems) + //{ + // if (hive.Equals(RegistryUtils.HKCR)) + // hives.Add($@"HKU\{userSID}\Software\Classes"); + // else if (hive.Equals(RegistryUtils.HKCU)) + // hives.Add($@"HKU\{userSID}"); + // else if (hive.Equals(RegistryUtils.HKLM)) + // hives.Add($@"HKLM"); + // else if (hive.Equals(RegistryUtils.HKU)) + // hives.Add($@"HKU"); + // else if (hive.Equals(RegistryUtils.HKCC)) + // hives.Add($@"HKLM\SYSTEM\CurrentControlSet\Hardware Profiles\Current"); + //} + #endregion experimental + } + else + { + foreach (string hive in cbxsHkeys.CheckedItems) + hives.Add(hive); + } + + return hives; + } + + private List GenerateRegQueryProcs(List hives) + { + List procs = new List(); + foreach (string hive in hives) + { + string searchQuery = BuildSearchQuery(RegistryUtils.GetHiveShortcut(hive)); + Process proc = CreateRegQueryProc(searchQuery); + procs.Add(proc); + Console.WriteLine($"{proc.StartInfo.FileName} {proc.StartInfo.Arguments}"); + } + + return procs; + } + + private string BuildSearchQuery(string hive) + { + string query = String.Empty; + + if (cbxRemoteSearch.Checked) + query = $"\"\\\\{tbxRemoteComputer.Text}\\{hive}\" /f \"{tbxSearch.Text}\" /s"; + else + query = $"\"{hive}\" /f \"{tbxSearch.Text}\" /s"; + + if (cbxKeys.Checked) query += " /k"; + if (cbxValues.Checked) query += " /v"; + if (cbxData.Checked) query += " /d"; + if (cbxCaseSensitive.Checked) query += " /c"; + if (cbxMatchString.Checked) query += " /e"; + if (cbxsDataTypes.GetItemCheckedByName("REG_MULTI_SZ")) query += " /se +"; + + if (cbxsDataTypes.CheckedItems.Count <= 0 || cbxsDataTypes.SelectAllChecked) + return query; + + // ------------------------ Adding Data types filters ------------------------ + query += " /t \""; + foreach (string checkedItem in cbxsDataTypes.CheckedItems) + query += checkedItem + ","; + + query = query.TrimEnd(','); + query += "\""; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb773476(v=vs.85).aspx + // Unfortunately these are not supported by reg query when filtering... + query = Regex.Replace(query, ",?REG_QWORD_LITTLE_ENDIAN", String.Empty); + query = Regex.Replace(query, ",?REG_LINK", String.Empty); + query = Regex.Replace(query, ",?REG_RESOURCE_LIST", String.Empty); + + return query; + } + + private Process CreateRegQueryProc(string searchQuery) + { + ProcessStartInfo procInfo = new ProcessStartInfo + { + FileName = "REG", + Arguments = $"QUERY {searchQuery}", + RedirectStandardError = true, + RedirectStandardInput = true, + RedirectStandardOutput = true, + CreateNoWindow = true, + UseShellExecute = false + }; + + Process proc = new Process + { + StartInfo = procInfo, + EnableRaisingEvents = true + }; + + proc.ErrorDataReceived += OnErrorDataReceived; + proc.OutputDataReceived += OnOutputDataReceived; + proc.Exited += OnFindEnd; + + return proc; + } + + private async Task ExecuteProcs(IEnumerable procs) + { + foreach (Process proc in procs) + { + procsExecuted++; + + string hiveShort = proc.StartInfo.Arguments.Split('"')[1]; + string hive = cbxRemoteSearch.Checked + ? RegistryUtils.GetRemoteHiveFullName(hiveShort) + : RegistryUtils.GetHiveFullName(hiveShort); + string message = $"Searching in {hive}...Patient :)"; + Text = $"Find | {message}"; + + OnProgressChanged(this, new ProgressChangedArgs(message, hive)); + await Task.Run(() => ExecuteProc(proc)); + + if (cancelToken.IsCancellationRequested) + break; + } + } + + private void ExecuteProc(Process proc) + { + proc.Start(); + proc.BeginErrorReadLine(); + proc.BeginOutputReadLine(); + + Console.WriteLine("[Process::ExecuteProc] - Waiting for exit..."); + proc.WaitForExit(); + Console.WriteLine("[Process::ExecuteProc] - Executed Finished."); + } + + private void OnOutputDataReceived(object sender, DataReceivedEventArgs e) + { + if (e?.Data == null) return; + + string hive = e.Data.TrimStart().StartsWith("HKEY_") ? e.Data : String.Empty; + if (String.IsNullOrEmpty(hive)) return; + + if (cbxRemoteSearch.Checked) + hive = $"{tbxRemoteComputer.Text}\\{hive}"; + + OnFoundSingleResult(this, new FindSingleResultArgs(hive)); + } + + private void OnErrorDataReceived(object sender, DataReceivedEventArgs e) + { + if (e?.Data == null) return; + if (!e.Data.StartsWith("ERROR")) return; + + if (e.Data.Trim().StartsWith("ERROR: The network path was not found.")) + { + MessageBox.Show($"{e.Data}\n" + + "Make sure that the target machine has \"Remote Registry\" service running.", + "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); + + cancelSrc.Cancel(); + } + else + { + MessageBox.Show("Error occured. Please contact author of this app with this message.\n" + + $"{e.Data}", + "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + + private async void OnFindEnd(object sender, EventArgs e) + { + if (procsList.Count != procsExecuted || procsExecuted == 0) return; + + await Task.Run(() => Thread.Sleep(1000)); + Console.WriteLine("[Process::OnFindEnd] - Waiting for other thread to finished."); + procToken.WaitOne(); + Console.WriteLine("[Process::OnFindEnd] - Clearing up."); + for (int i = 0; i < procsList.Count; i++) + { + procsList[i].Dispose(); + procsList[i] = null; + } + + searchInProgress = false; + loader.Hide(); + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + if (!searchInProgress) return; + + cancelSrc.Cancel(); + for (int i = 0; i < procsExecuted; i++) + { + procsList[i].CancelErrorRead(); + procsList[i].CancelOutputRead(); + if (!procsList[i].HasExited) + procsList[i].Kill(); + } + + procToken.Set(); + } + + private void CbxSearchInRemote_CheckedChanged(object sender, EventArgs e) + { + tbxRemoteComputer.Enabled = cbxRemoteSearch.Checked; + btnFindAvailableMachines.Enabled = cbxRemoteSearch.Checked; + gbxHkeys.Enabled = !cbxRemoteSearch.Checked; + if (cbxRemoteSearch.Checked) + tbxRemoteComputer.Focus(); + else + tbxSearch.Focus(); + } + + private void FindWindow_KeyPress(object sender, KeyPressEventArgs e) + { + Keys key = (Keys) e.KeyChar; + switch (key) + { + case Keys.Escape: + Close(); + break; + + case Keys.Return: + btnFindAll.PerformClick(); + break; + } + } + + private async void FindWindow_FormClosing(object sender, FormClosingEventArgs e) + { + if (searchInProgress) + { + e.Cancel = true; + btnCancel.PerformClick(); + await Task.Run(() => Thread.Sleep(500)); + Close(); + } + } + + + #region --- Events --- + + public event Action FoundResults; + public event Action FoundSingleResult; + public event Action ProgressStarted; + public event Action ProgressChanged; + public event Action ProgressFinished; + + protected virtual void OnFoundResults(object sender, FindResultsArgs e) => FoundResults?.Invoke(sender, e); + + protected virtual void OnFoundSingleResult(object sender, FindSingleResultArgs e) => FoundSingleResult?.Invoke(sender, e); + + protected virtual void OnProgressStarted(object sender, ProgressStartedArgs e) => ProgressStarted?.Invoke(sender, e); + + protected virtual void OnProgressChanged(object sender, ProgressChangedArgs e) => ProgressChanged?.Invoke(sender, e); + + protected virtual void OnProgressFinished(object sender, ProgressFinishedArgs e) => ProgressFinished?.Invoke(sender, e); + + #endregion --- Events --- + + #region Slow As Hell + + //using LogQuery = Interop.MSUtil.LogQueryClass; + //using RegistryInputFormat = Interop.MSUtil.COMRegistryInputContextClass; + //using RegRecordSet = Interop.MSUtil.ILogRecordset; + + //private void BtnFindSingle_Click(object sender, EventArgs e) + //{ + // matches = new List(); + // RegRecordSet rs = null; + // try + // { + // LogQuery qry = new LogQuery(); + // RegistryInputFormat registryFormat = new RegistryInputFormat(); + // string query = $@"SELECT Path FROM HKLM WHERE Value='{tbxSearch.Text}'"; + // rs = qry.Execute(query, registryFormat); + // for (; !rs.atEnd(); rs.moveNext()) + // { + // matches.Add(rs.getRecord().toNativeString("")); + // } + // } + // finally + // { + // rs.close(); + // } + + // ((MainWindow)Owner).OnFoundResults(this, new FindResultsArgs(matches)); + // Close(); + //} + + #endregion Slow As Hell + } +} diff --git a/src/Windows.RegistryEditor/Views/MainWindow.Designer.cs b/src/Windows.RegistryEditor/Views/MainWindow.Designer.cs new file mode 100644 index 0000000..adfda85 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/MainWindow.Designer.cs @@ -0,0 +1,622 @@ +namespace Windows.RegistryEditor.Views +{ + partial class MainWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Computer"); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.loadHideToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.unloadHiveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.modifyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.modifyBinaryDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.keyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.stringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.binaryValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.dWORD32BitValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.dWORD64bitValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.multiStringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.expandableStringValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.permissionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.copyKeyNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); + this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.favoritesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addToFavoritesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeFavoritesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.treeView = new System.Windows.Forms.TreeView(); + this.splitContainer = new System.Windows.Forms.SplitContainer(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.cbxScrollToCaret = new System.Windows.Forms.CheckBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.cbxSelectAll = new System.Windows.Forms.CheckBox(); + this.btnDelete = new System.Windows.Forms.Button(); + this.lblResultsCount = new System.Windows.Forms.Label(); + this.lvwResults = new Windows.RegistryEditor.Views.Controls.ListViewEx(); + this.columnCbx = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHkey = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.cbx = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.HKEY = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.menuStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit(); + this.splitContainer.Panel1.SuspendLayout(); + this.splitContainer.Panel2.SuspendLayout(); + this.splitContainer.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.viewToolStripMenuItem, + this.favoritesToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(956, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.importToolStripMenuItem, + this.exportToolStripMenuItem, + this.toolStripSeparator2, + this.loadHideToolStripMenuItem, + this.unloadHiveToolStripMenuItem, + this.toolStripSeparator1, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "File"; + // + // importToolStripMenuItem + // + this.importToolStripMenuItem.Name = "importToolStripMenuItem"; + this.importToolStripMenuItem.Size = new System.Drawing.Size(148, 22); + this.importToolStripMenuItem.Text = "Import..."; + // + // exportToolStripMenuItem + // + this.exportToolStripMenuItem.Name = "exportToolStripMenuItem"; + this.exportToolStripMenuItem.Size = new System.Drawing.Size(148, 22); + this.exportToolStripMenuItem.Text = "Export..."; + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(145, 6); + // + // loadHideToolStripMenuItem + // + this.loadHideToolStripMenuItem.Name = "loadHideToolStripMenuItem"; + this.loadHideToolStripMenuItem.Size = new System.Drawing.Size(148, 22); + this.loadHideToolStripMenuItem.Text = "Load Hive..."; + // + // unloadHiveToolStripMenuItem + // + this.unloadHiveToolStripMenuItem.Name = "unloadHiveToolStripMenuItem"; + this.unloadHiveToolStripMenuItem.Size = new System.Drawing.Size(148, 22); + this.unloadHiveToolStripMenuItem.Text = "Unload Hive..."; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(145, 6); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(148, 22); + this.exitToolStripMenuItem.Text = "Exit"; + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.modifyToolStripMenuItem, + this.modifyBinaryDataToolStripMenuItem, + this.toolStripSeparator3, + this.newToolStripMenuItem, + this.toolStripSeparator5, + this.permissionsToolStripMenuItem, + this.toolStripSeparator6, + this.deleteToolStripMenuItem, + this.renameToolStripMenuItem, + this.toolStripSeparator7, + this.copyKeyNameToolStripMenuItem, + this.toolStripSeparator8, + this.findToolStripMenuItem, + this.findNextToolStripMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); + this.editToolStripMenuItem.Text = "Edit"; + // + // modifyToolStripMenuItem + // + this.modifyToolStripMenuItem.Name = "modifyToolStripMenuItem"; + this.modifyToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.modifyToolStripMenuItem.Text = "Modify..."; + // + // modifyBinaryDataToolStripMenuItem + // + this.modifyBinaryDataToolStripMenuItem.Name = "modifyBinaryDataToolStripMenuItem"; + this.modifyBinaryDataToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.modifyBinaryDataToolStripMenuItem.Text = "Modify Binary Data..."; + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(181, 6); + // + // newToolStripMenuItem + // + this.newToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.keyToolStripMenuItem, + this.toolStripSeparator4, + this.stringValueToolStripMenuItem, + this.binaryValueToolStripMenuItem, + this.dWORD32BitValueToolStripMenuItem, + this.dWORD64bitValueToolStripMenuItem, + this.multiStringValueToolStripMenuItem, + this.expandableStringValueToolStripMenuItem}); + this.newToolStripMenuItem.Name = "newToolStripMenuItem"; + this.newToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.newToolStripMenuItem.Text = "New"; + // + // keyToolStripMenuItem + // + this.keyToolStripMenuItem.Name = "keyToolStripMenuItem"; + this.keyToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.keyToolStripMenuItem.Text = "Key"; + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(196, 6); + // + // stringValueToolStripMenuItem + // + this.stringValueToolStripMenuItem.Name = "stringValueToolStripMenuItem"; + this.stringValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.stringValueToolStripMenuItem.Text = "String Value"; + // + // binaryValueToolStripMenuItem + // + this.binaryValueToolStripMenuItem.Name = "binaryValueToolStripMenuItem"; + this.binaryValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.binaryValueToolStripMenuItem.Text = "Binary Value"; + // + // dWORD32BitValueToolStripMenuItem + // + this.dWORD32BitValueToolStripMenuItem.Name = "dWORD32BitValueToolStripMenuItem"; + this.dWORD32BitValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.dWORD32BitValueToolStripMenuItem.Text = "DWORD (32-bit) Value"; + // + // dWORD64bitValueToolStripMenuItem + // + this.dWORD64bitValueToolStripMenuItem.Name = "dWORD64bitValueToolStripMenuItem"; + this.dWORD64bitValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.dWORD64bitValueToolStripMenuItem.Text = "QWORD (64-bit) Value"; + // + // multiStringValueToolStripMenuItem + // + this.multiStringValueToolStripMenuItem.Name = "multiStringValueToolStripMenuItem"; + this.multiStringValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.multiStringValueToolStripMenuItem.Text = "Multi-String Value"; + // + // expandableStringValueToolStripMenuItem + // + this.expandableStringValueToolStripMenuItem.Name = "expandableStringValueToolStripMenuItem"; + this.expandableStringValueToolStripMenuItem.Size = new System.Drawing.Size(199, 22); + this.expandableStringValueToolStripMenuItem.Text = "Expandable String Value"; + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(181, 6); + // + // permissionsToolStripMenuItem + // + this.permissionsToolStripMenuItem.Name = "permissionsToolStripMenuItem"; + this.permissionsToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.permissionsToolStripMenuItem.Text = "Permissions..."; + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(181, 6); + // + // deleteToolStripMenuItem + // + this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; + this.deleteToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.deleteToolStripMenuItem.Text = "Delete"; + // + // renameToolStripMenuItem + // + this.renameToolStripMenuItem.Name = "renameToolStripMenuItem"; + this.renameToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.renameToolStripMenuItem.Text = "Rename"; + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(181, 6); + // + // copyKeyNameToolStripMenuItem + // + this.copyKeyNameToolStripMenuItem.Name = "copyKeyNameToolStripMenuItem"; + this.copyKeyNameToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.copyKeyNameToolStripMenuItem.Text = "Copy Key Name"; + // + // toolStripSeparator8 + // + this.toolStripSeparator8.Name = "toolStripSeparator8"; + this.toolStripSeparator8.Size = new System.Drawing.Size(181, 6); + // + // findToolStripMenuItem + // + this.findToolStripMenuItem.Name = "findToolStripMenuItem"; + this.findToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.findToolStripMenuItem.Text = "Find..."; + this.findToolStripMenuItem.Click += new System.EventHandler(this.FindToolStripMenuItem_Click); + // + // findNextToolStripMenuItem + // + this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; + this.findNextToolStripMenuItem.Size = new System.Drawing.Size(184, 22); + this.findNextToolStripMenuItem.Text = "Find Next"; + // + // viewToolStripMenuItem + // + this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; + this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.viewToolStripMenuItem.Text = "View"; + // + // favoritesToolStripMenuItem + // + this.favoritesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addToFavoritesToolStripMenuItem, + this.removeFavoritesToolStripMenuItem}); + this.favoritesToolStripMenuItem.Name = "favoritesToolStripMenuItem"; + this.favoritesToolStripMenuItem.Size = new System.Drawing.Size(66, 20); + this.favoritesToolStripMenuItem.Text = "Favorites"; + // + // addToFavoritesToolStripMenuItem + // + this.addToFavoritesToolStripMenuItem.Name = "addToFavoritesToolStripMenuItem"; + this.addToFavoritesToolStripMenuItem.Size = new System.Drawing.Size(176, 22); + this.addToFavoritesToolStripMenuItem.Text = "Add to Favorites..."; + // + // removeFavoritesToolStripMenuItem + // + this.removeFavoritesToolStripMenuItem.Name = "removeFavoritesToolStripMenuItem"; + this.removeFavoritesToolStripMenuItem.Size = new System.Drawing.Size(176, 22); + this.removeFavoritesToolStripMenuItem.Text = "Remove Favorites..."; + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "Help"; + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.aboutToolStripMenuItem.Text = "About Registry Editor..."; + // + // treeView + // + this.treeView.Dock = System.Windows.Forms.DockStyle.Fill; + this.treeView.Location = new System.Drawing.Point(0, 0); + this.treeView.Name = "treeView"; + treeNode1.Name = "Computer"; + treeNode1.Text = "Computer"; + this.treeView.Nodes.AddRange(new System.Windows.Forms.TreeNode[] { + treeNode1}); + this.treeView.Size = new System.Drawing.Size(202, 536); + this.treeView.TabIndex = 0; + // + // splitContainer + // + this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer.Location = new System.Drawing.Point(0, 24); + this.splitContainer.Name = "splitContainer"; + // + // splitContainer.Panel1 + // + this.splitContainer.Panel1.Controls.Add(this.treeView); + // + // splitContainer.Panel2 + // + this.splitContainer.Panel2.Controls.Add(this.splitContainer1); + this.splitContainer.Size = new System.Drawing.Size(956, 536); + this.splitContainer.SplitterDistance = 202; + this.splitContainer.TabIndex = 2; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.cbxScrollToCaret); + this.splitContainer1.Panel1.Controls.Add(this.label3); + this.splitContainer1.Panel1.Controls.Add(this.label2); + this.splitContainer1.Panel1.Controls.Add(this.cbxSelectAll); + this.splitContainer1.Panel1.Controls.Add(this.btnDelete); + this.splitContainer1.Panel1.Controls.Add(this.lblResultsCount); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.lvwResults); + this.splitContainer1.Panel2.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.splitContainer1.Size = new System.Drawing.Size(750, 536); + this.splitContainer1.SplitterDistance = 47; + this.splitContainer1.TabIndex = 0; + // + // cbxScrollToCaret + // + this.cbxScrollToCaret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cbxScrollToCaret.AutoSize = true; + this.cbxScrollToCaret.Checked = true; + this.cbxScrollToCaret.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxScrollToCaret.Location = new System.Drawing.Point(585, 30); + this.cbxScrollToCaret.Name = "cbxScrollToCaret"; + this.cbxScrollToCaret.Size = new System.Drawing.Size(147, 17); + this.cbxScrollToCaret.TabIndex = 5; + this.cbxScrollToCaret.Text = "Automatically scroll down."; + this.cbxScrollToCaret.UseVisualStyleBackColor = true; + // + // label3 + // + this.label3.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(219, 23); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(275, 13); + this.label3.TabIndex = 4; + this.label3.Text = "Right Click on one of the results lines to see some magic."; + // + // label2 + // + this.label2.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(219, 5); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(162, 13); + this.label2.TabIndex = 4; + this.label2.Text = "CTRL + F to search for registries."; + // + // cbxSelectAll + // + this.cbxSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxSelectAll.AutoSize = true; + this.cbxSelectAll.Checked = true; + this.cbxSelectAll.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbxSelectAll.Location = new System.Drawing.Point(7, 29); + this.cbxSelectAll.Name = "cbxSelectAll"; + this.cbxSelectAll.Size = new System.Drawing.Size(70, 17); + this.cbxSelectAll.TabIndex = 1; + this.cbxSelectAll.Text = "Select All"; + this.cbxSelectAll.UseVisualStyleBackColor = true; + this.cbxSelectAll.CheckedChanged += new System.EventHandler(this.CbxSelectAll_CheckedChanged); + // + // btnDelete + // + this.btnDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnDelete.Location = new System.Drawing.Point(583, 5); + this.btnDelete.Name = "btnDelete"; + this.btnDelete.Size = new System.Drawing.Size(164, 23); + this.btnDelete.TabIndex = 2; + this.btnDelete.Text = "Delete All Selected Registries"; + this.btnDelete.UseVisualStyleBackColor = true; + this.btnDelete.Click += new System.EventHandler(this.BtnDelete_Click); + // + // lblResultsCount + // + this.lblResultsCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblResultsCount.AutoSize = true; + this.lblResultsCount.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblResultsCount.Location = new System.Drawing.Point(5, 8); + this.lblResultsCount.Name = "lblResultsCount"; + this.lblResultsCount.Size = new System.Drawing.Size(128, 17); + this.lblResultsCount.TabIndex = 1; + this.lblResultsCount.Text = "Results Count: 0"; + // + // lvwResults + // + this.lvwResults.CheckBoxes = true; + this.lvwResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnCbx, + this.columnHkey}); + this.lvwResults.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvwResults.FullRowSelect = true; + this.lvwResults.GridLines = true; + this.lvwResults.Location = new System.Drawing.Point(0, 0); + this.lvwResults.Name = "lvwResults"; + this.lvwResults.Size = new System.Drawing.Size(750, 485); + this.lvwResults.TabIndex = 0; + this.lvwResults.UseCompatibleStateImageBehavior = false; + this.lvwResults.View = System.Windows.Forms.View.Details; + this.lvwResults.MouseClick += new System.Windows.Forms.MouseEventHandler(this.LvwResults_MouseClick); + // + // columnCbx + // + this.columnCbx.Text = ""; + this.columnCbx.Width = 24; + // + // columnHkey + // + this.columnHkey.Text = "HKEY"; + this.columnHkey.Width = 1980; + // + // MainWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(956, 560); + this.Controls.Add(this.splitContainer); + this.Controls.Add(this.menuStrip1); + this.DoubleBuffered = true; + this.Icon = global::Windows.RegistryEditor.Properties.Resources.app; + this.KeyPreview = true; + this.MainMenuStrip = this.menuStrip1; + this.Name = "MainWindow"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Registry Editor"; + this.Load += new System.EventHandler(this.MainWindow_Load); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainWindow_KeyDown); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.splitContainer.Panel1.ResumeLayout(false); + this.splitContainer.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit(); + this.splitContainer.ResumeLayout(false); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + private void InitializeRegistryTree() + { + treeView.TopNode.Nodes.Add(Microsoft.Win32.Registry.ClassesRoot.Name, Microsoft.Win32.Registry.ClassesRoot.Name); + treeView.TopNode.Nodes.Add(Microsoft.Win32.Registry.CurrentUser.Name, Microsoft.Win32.Registry.CurrentUser.Name); + treeView.TopNode.Nodes.Add(Microsoft.Win32.Registry.LocalMachine.Name, Microsoft.Win32.Registry.LocalMachine.Name); + treeView.TopNode.Nodes.Add(Microsoft.Win32.Registry.Users.Name, Microsoft.Win32.Registry.Users.Name); + treeView.TopNode.Nodes.Add(Microsoft.Win32.Registry.CurrentConfig.Name, Microsoft.Win32.Registry.CurrentConfig.Name); + + treeView.TopNode.Nodes[Microsoft.Win32.Registry.ClassesRoot.Name].Nodes.Add(System.String.Empty); + treeView.TopNode.Nodes[Microsoft.Win32.Registry.CurrentUser.Name].Nodes.Add(System.String.Empty); + treeView.TopNode.Nodes[Microsoft.Win32.Registry.LocalMachine.Name].Nodes.Add(System.String.Empty); + treeView.TopNode.Nodes[Microsoft.Win32.Registry.Users.Name].Nodes.Add(System.String.Empty); + treeView.TopNode.Nodes[Microsoft.Win32.Registry.CurrentConfig.Name].Nodes.Add(System.String.Empty); + + treeView.TopNode.Nodes[Microsoft.Win32.Registry.ClassesRoot.Name].Tag = Microsoft.Win32.Registry.ClassesRoot; + treeView.TopNode.Nodes[Microsoft.Win32.Registry.CurrentUser.Name].Tag = Microsoft.Win32.Registry.CurrentUser; + treeView.TopNode.Nodes[Microsoft.Win32.Registry.LocalMachine.Name].Tag = Microsoft.Win32.Registry.LocalMachine; + treeView.TopNode.Nodes[Microsoft.Win32.Registry.Users.Name].Tag = Microsoft.Win32.Registry.Users; + treeView.TopNode.Nodes[Microsoft.Win32.Registry.CurrentConfig.Name].Tag = Microsoft.Win32.Registry.CurrentConfig; + + treeView.TopNode.Expand(); + + treeView.BeforeExpand += TreeViewBeforeExpand; + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem loadHideToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem unloadHiveToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem modifyToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem modifyBinaryDataToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem keyToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem stringValueToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem binaryValueToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem dWORD32BitValueToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem dWORD64bitValueToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem multiStringValueToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem expandableStringValueToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem permissionsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem copyKeyNameToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; + private System.Windows.Forms.ToolStripMenuItem findToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findNextToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem favoritesToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addToFavoritesToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeFavoritesToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.TreeView treeView; + private System.Windows.Forms.SplitContainer splitContainer; + private System.Windows.Forms.Label lblResultsCount; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.ColumnHeader cbx; + private System.Windows.Forms.ColumnHeader HKEY; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.CheckBox cbxSelectAll; + private Windows.RegistryEditor.Views.Controls.ListViewEx lvwResults; + private System.Windows.Forms.ColumnHeader columnCbx; + private System.Windows.Forms.ColumnHeader columnHkey; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox cbxScrollToCaret; + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Views/MainWindow.cs b/src/Windows.RegistryEditor/Views/MainWindow.cs new file mode 100644 index 0000000..cfa2884 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/MainWindow.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using Windows.RegistryEditor.Events; +using Windows.RegistryEditor.Utils; +using Microsoft.Win32; + +using static System.Environment; + +namespace Windows.RegistryEditor.Views +{ + public partial class MainWindow : Form + { + + private FindWindow refFindWindow; + public FindWindow FindInstance + { + get + { + if (refFindWindow != null && !refFindWindow.IsDisposed) + { + refFindWindow.Activate();; + return refFindWindow; + } + refFindWindow = new FindWindow(); + refFindWindow.FoundSingleResult += SingleResultFound; + refFindWindow.ProgressStarted += ProgressStarted; + refFindWindow.ProgressChanged += ProgressChanged; + refFindWindow.ProgressFinished += ProgressFinished; + refFindWindow.FormClosed += delegate { this.Activate(); }; + return refFindWindow; + } + } + + private void ProgressStarted(object sender, ProgressStartedArgs e) + { + lvwResults.Items.Clear(); + lblResultsCount.Text = "Results Count: 0"; + Console.WriteLine(e.Message); + } + + private void ProgressChanged(object sender, ProgressChangedArgs e) + { + Text = $"Registry Editor | Collecting Data from {e.Hive}"; + Console.WriteLine(e.Message); + } + + private void ProgressFinished(object sender, ProgressFinishedArgs e) + { + Text = "Registry Editor"; + Console.WriteLine(e.Message); + } + + + public MainWindow() + { + InitializeComponent(); + } + + private void MainWindow_Load(object sender, EventArgs e) + { + InitializeRegistryTree(); + } + + private void TreeViewBeforeExpand(object sender, TreeViewCancelEventArgs e) + { + if (e.Node.Nodes.Count != 1 || e.Node.Nodes[0].Text != String.Empty) return; + + e.Node.Nodes.Clear(); + if (!(e.Node.Tag is RegistryKey key)) return; + + foreach (string name in key.GetSubKeyNames()) + { + e.Node.Nodes.Add(name, name); + if (name == "SECURITY" || name == "SAM") continue; + + RegistryKey subKey = key.OpenSubKey(name); + e.Node.Nodes[name].Tag = subKey; + if (subKey.SubKeyCount > 0) + e.Node.Nodes[name].Nodes.Add(String.Empty); + } + } + + private async void SingleResultFound(object sender, FindSingleResultArgs e) + { + await Task.Run(() => + lvwResults.InvokeSafe(() => + AddItem(e.Match, true, cbxScrollToCaret.Checked) + )); + } + + private void AddItem(string text, bool isChecked, bool isVisible) + { + ListViewItem item = new ListViewItem(); + item.SubItems.Add(text); + item.Checked = isChecked; + + lvwResults.Items.Add(item); + int count = lvwResults.Items.Count; + lblResultsCount.Text = $"Results Count: {count}"; + if (isVisible) + lvwResults.EnsureVisible(count - 1); + //lvwResults.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); + } + + private void MainWindow_KeyDown(object sender, KeyEventArgs e) + { + if (e.Control && e.KeyCode == Keys.F) + { + if (!FindInstance.Visible) + FindInstance.Show(this); + } + else if (lvwResults.Focused && e.Control && e.KeyCode == Keys.C) + { + Clipboard.SetData(DataFormats.StringFormat, lvwResults.GetAllSelectedSubItemsText(1)); + } + else if (lvwResults.Focused && e.Control && e.KeyCode == Keys.A) + { + lvwResults.SelectAllItems(); + } + } + + private void LvwResults_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + RegistryUtils.OpenRegistryLocation(lvwResults.FocusedItem.SubItems[1].Text); + } + + private void CbxSelectAll_CheckedChanged(object sender, EventArgs e) + { + lvwResults.CheckAllItems(cbxSelectAll.Checked); + } + + private void BtnDelete_Click(object sender, EventArgs e) + { + List hives = lvwResults.GetAllCheckedSubItemsTextList(1); + if (hives.Count < 1) return; + + if (!hives.First().StartsWith("HKEY_")) + { + MessageBox.Show("Deleting or Exporting registry keys on remote machines not implemented.", + "NOT IMPLEMENTED", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + DialogResult result = MessageBox.Show( + "All registries that are checked will be removed from registry including sub keys.\n" + + "Are you sure you want to continue?", "WARNING", + MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2); + + if (result != DialogResult.Yes) return; + + string dstDir = Path.Combine(GetFolderPath(SpecialFolder.Desktop), "Registry_Backup", $"{DateTime.Now:yy-MM-dd_hh-mm}"); + foreach (string hive in hives) + { + RegistryUtils.ExportHive(hive, dstDir); + RegistryUtils.DeleteHive(hive); + Console.WriteLine($"Registry Deleted: {hive}"); + } + + MessageBox.Show("Successfully removed checked registries.\n" + + "Created emergency backup of the removed registries on your desktop.", + "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Information); + + Utility.OpenFolderInExplorer(dstDir); + } + + private void FindToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!FindInstance.Visible) + FindInstance.Show(this); + } + + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED + return cp; + } + } + } +} diff --git a/src/Windows.RegistryEditor/Views/NetworkWindow.Designer.cs b/src/Windows.RegistryEditor/Views/NetworkWindow.Designer.cs new file mode 100644 index 0000000..7f0d917 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/NetworkWindow.Designer.cs @@ -0,0 +1,94 @@ +namespace Windows.RegistryEditor.Views +{ + partial class NetworkWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lbxMachines = new System.Windows.Forms.ListBox(); + this.btnSelect = new System.Windows.Forms.Button(); + this.loader = new Windows.RegistryEditor.Views.Controls.Loader(); + this.SuspendLayout(); + // + // lbxMachines + // + this.lbxMachines.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lbxMachines.FormattingEnabled = true; + this.lbxMachines.Location = new System.Drawing.Point(12, 19); + this.lbxMachines.Name = "lbxMachines"; + this.lbxMachines.Size = new System.Drawing.Size(179, 95); + this.lbxMachines.TabIndex = 0; + // + // btnSelect + // + this.btnSelect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnSelect.Location = new System.Drawing.Point(103, 120); + this.btnSelect.Name = "btnSelect"; + this.btnSelect.Size = new System.Drawing.Size(88, 23); + this.btnSelect.TabIndex = 2; + this.btnSelect.Text = "Select"; + this.btnSelect.UseVisualStyleBackColor = true; + this.btnSelect.Click += new System.EventHandler(this.BtnSelect_Click); + // + // loader + // + this.loader.BackColor = System.Drawing.Color.Transparent; + this.loader.DisableControlsOnWork = true; + this.loader.LoaderKind = Windows.RegistryEditor.Views.Controls.LoaderKind.Clock; + this.loader.Location = new System.Drawing.Point(12, 123); + this.loader.Name = "loader"; + this.loader.Size = new System.Drawing.Size(20, 20); + this.loader.SizeLoading = new System.Drawing.Size(60, 60); + this.loader.TabIndex = 3; + this.loader.Visible = false; + // + // NetworkWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(203, 155); + this.Controls.Add(this.loader); + this.Controls.Add(this.btnSelect); + this.Controls.Add(this.lbxMachines); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Name = "NetworkWindow"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Machines on the Network"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NetworkWindow_FormClosing); + this.Load += new System.EventHandler(this.NetworkWindow_Load); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ListBox lbxMachines; + private System.Windows.Forms.Button btnSelect; + private Controls.Loader loader; + } +} \ No newline at end of file diff --git a/src/Windows.RegistryEditor/Views/NetworkWindow.cs b/src/Windows.RegistryEditor/Views/NetworkWindow.cs new file mode 100644 index 0000000..15ea328 --- /dev/null +++ b/src/Windows.RegistryEditor/Views/NetworkWindow.cs @@ -0,0 +1,106 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Windows.RegistryEditor.Utils; + +namespace Windows.RegistryEditor.Views +{ + public partial class NetworkWindow : Form + { + private Process proc; + + public NetworkWindow() + { + InitializeComponent(); + } + + private async void NetworkWindow_Load(object sender, EventArgs e) + { + lbxMachines.Items.Clear(); + + loader.Show(); + ProcessStartInfo procInfo = new ProcessStartInfo + { + FileName = "NET", + Arguments = "VIEW", + RedirectStandardError = true, + RedirectStandardInput = true, + RedirectStandardOutput = true, + CreateNoWindow = true, + UseShellExecute = false + }; + + proc = new Process + { + StartInfo = procInfo, + EnableRaisingEvents = true + }; + + proc.ErrorDataReceived += OnErrorDataReceived; + proc.OutputDataReceived += OnOutputDataReceived; + proc.Exited += OnFindEnd; + + await Task.Run(() => Execute(proc)); + } + + private void Execute(Process proc) + { + proc.Start(); + proc.BeginErrorReadLine(); + proc.BeginOutputReadLine(); + proc.WaitForExit(); + } + + private void OnOutputDataReceived(object sender, DataReceivedEventArgs e) + { + if (e.Data == null) return; + if (!e.Data.StartsWith(@"\\")) return; + + lbxMachines.InvokeSafe(() => lbxMachines.Items.Add(e.Data.Trim())); + } + + private void OnErrorDataReceived(object sender, DataReceivedEventArgs e) + { + Console.WriteLine("ERROR occured while searching for network devices -> " + e.Data); + loader.Hide(); + } + + private void OnFindEnd(object sender, EventArgs e) + { + Console.WriteLine("Finished searching for network devices."); + loader.Hide(); + + proc = null; + } + + private void BtnSelect_Click(object sender, EventArgs e) + { + string machineName = lbxMachines.SelectedItem.ToString(); + OnMachineSelected(machineName.Replace(@"\\", String.Empty)); + Close(); + } + + private async void NetworkWindow_FormClosing(object sender, FormClosingEventArgs e) + { + if (proc != null) + { + e.Cancel = true; + proc.CancelErrorRead(); + proc.CancelOutputRead(); + await Task.Run(() => Thread.Sleep(100)); + proc.Kill(); + proc.Dispose(); + proc = null; + await Task.Run(() => Thread.Sleep(500)); + + Close(); + } + } + + public event Action MachineSelected; + + protected virtual void OnMachineSelected(string e) => MachineSelected?.Invoke(e); + } +} diff --git a/src/Windows.RegistryEditor/app.manifest b/src/Windows.RegistryEditor/app.manifest new file mode 100644 index 0000000..4670159 --- /dev/null +++ b/src/Windows.RegistryEditor/app.manifest @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +