UWPSettingsEditor
MainWindow.xaml.cs
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System;
using System.Windows.Media.Imaging;
using static UWPSettingsEditor.NativeMethods;
using System.IO;
using System.Windows.Input;
using System.Text;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Media;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Media;
using System.Linq;
using DiscUtils.Registry;
using RegistryKey = DiscUtils.Registry.RegistryKey;
using System.Windows.Data;
using System.Collections.ObjectModel;
using UWPSettingsEditor.Windows;
namespace UWPSettingsEditor
{
///
/// Interaction logic for MainWindow.xaml
///
public partial clast MainWindow : Window
{
//TODO: localize messages
private readonly List treeRoot = new List();
private readonly ObservableCollection keyVals = new ObservableCollection();
private readonly BitmapSource computerBitmap;
private readonly BitmapSource folderBitmap;
public MainWindow()
{
InitializeComponent();
//var uwu = new DiscUtils.Registry.RegistryHive(new FileStream(@"C:\Users\ADelt\Docameents\settings.dat", FileMode.Open));
//var e = uwu.Root.OpenSubKey("LocalState").GetValueType("hasUnreadValuesBOOL");
WindowState = WindowState.Minimized;
computerBitmap = ExtractIcon("Shell32.dll", 15, false);
folderBitmap = ExtractIcon("Shell32.dll", 3, false);
selectedIconImage.Source = computerBitmap;
treeRoot.Add(new RootTreeView() { Name = "Computer", ImageSource = computerBitmap });
treeView.ItemsSource = treeRoot;
listView.ItemsSource = keyVals;
//Darkmode
var hndl = new WindowInteropHelper(this).EnsureHandle();
IntPtr brush = CreateSolidBrush(uint.MinValue);
SetClastLong(hndl, -10, brush);
SetWindowTheme(hndl, "DarkMode_Explorer", IntPtr.Zero);
int attrValue = 1; //TRUE
DwmSetWindowAttribute(hndl, 20, ref attrValue, Marshal.SizeOf(typeof(int)));
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Activate();
WindowState = WindowState.Normal;
}
private void LoadAndVerifyHives(string[] filenames)
{
//TODO: background thread processing.
bool isMoreThanOneFile = filenames.Length > 1;
StringBuilder aggregatedMessages = null;
if (isMoreThanOneFile)
aggregatedMessages = new StringBuilder();
foreach (var file in filenames)
{
var isloaded = IsHiveAlreadyLoaded(file);
if (isloaded)
{
//ToDo: more meaningful warning message
if (isMoreThanOneFile)
aggregatedMessages.AppendLine("This registry hive is already loaded\nFile: " + file + "\n");
else
MessageBox.Show("This registry hive is already loaded\nFile: " + file, "Hive already loaded", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
else
{
try
{
var res = LoadHive(file, true); //TEST
if (res)
{
//Get the root item (as treeviewitem given the datatemplate) and open it
var uwu = treeView.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;
uwu.IsExpanded = true;
}
}
catch (Exception ex)
{
if (isMoreThanOneFile)
aggregatedMessages.AppendLine("This registry hive couldn't be loaded\nDetails: " + ex.Message + "\n");
else
MessageBox.Show("This registry hive couldn't be loaded\nDetails: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
if (isMoreThanOneFile && aggregatedMessages.Length > 0)
MessageBox.Show(aggregatedMessages.ToString(), "Multiple messages", MessageBoxButton.OK, MessageBoxImage.Exclamation);
}
private bool LoadHive(string filename, bool onDemand)
{
var root = treeRoot[0];
var hive = new RegistryHive(new FileStream(filename, FileMode.Open));
var rootKey = hive.Root;
if (rootKey != null)
{
var t_hive = new RegistryHiveTreeView(hive)
{
Name = Path.GetFileName(filename),
FilePath = filename,
ImageSource = folderBitmap
};
root.RegistryHiveTreeViews.Add(t_hive);
if (rootKey.SubKeys != null && rootKey.GetSubKeyNames().Length > 0)
t_hive.LoadDummyChild();
return true;
}
else
{
return false;
}
}
private void LoadSubkeyRoot(RegistryHiveTreeView registryHiveTreeView)
{
if (registryHiveTreeView.IsDummy)
registryHiveTreeView.RemoveDummyChild();
var regKeyTreeViews = GetRegistryKeyTreeViews(registryHiveTreeView.AttachedHive, "\\");
for (int i = 0; i < regKeyTreeViews.Length; i++)
{
regKeyTreeViews[i].Root = registryHiveTreeView;
registryHiveTreeView.Children.Add(regKeyTreeViews[i]);
}
}
private void LoadSubkey(RegistryKeyTreeView regKey)
{
if (regKey.IsDummy)
regKey.RemoveDummyChild();
var regKeyTreeViews = GetRegistryKeyTreeViews(regKey.AttachedHive, regKey.Path);
for (int i = 0; i < regKeyTreeViews.Length; i++)
{
regKeyTreeViews[i].Root = regKey.Root;
regKey.Children.Add(regKeyTreeViews[i]);
}
}
private RegistryKeyTreeView[] GetRegistryKeyTreeViews(RegistryHive registryHive, string registryKeyPath)
{
var subKey = (registryKeyPath == "\\") ? registryHive.Root : registryHive.Root.OpenSubKey(registryKeyPath);
RegistryKeyTreeView[] registryKeyTreeViews = new RegistryKeyTreeView[subKey.SubKeyCount];
var i = 0;
foreach (var subKeyDet in subKey.SubKeys)
{
var regChild = new RegistryKeyTreeView
{
AttachedHive = registryHive,
ImageSource = folderBitmap,
Name = subKeyDet.Name.Split('\\').Last(), //TODO
Path = subKeyDet.Name
};
if (subKeyDet.SubKeyCount > 0)
regChild.LoadDummyChild();
registryKeyTreeViews[i] = regChild;
i++;
}
return registryKeyTreeViews;
}
private bool IsHiveAlreadyLoaded(string filename)
{
foreach (var regHive in treeRoot[0].RegistryHiveTreeViews)
{
var p1 = Path.GetFullPath(filename);
var p2 = Path.GetFullPath(regHive.FilePath);
if (string.Equals(p1, p2, StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
private void treeView_Expanded(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is TreeViewItem tvi)
{
if (tvi.DataContext is RegistryHiveTreeView registryHiveTreeView)
{
if (registryHiveTreeView.IsDummy)
{
LoadSubkeyRoot(registryHiveTreeView);
}
}
else if (tvi.DataContext is RegistryKeyTreeView registryKeyTreeView)
{
if (registryKeyTreeView.IsDummy)
{
LoadSubkey(registryKeyTreeView);
}
}
}
}
private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue)
return;
keyVals.Clear();
void PopulateListView(RegistryKey registryKey, RegistryHive registryBase)
{
if (registryKey.ValueCount > 0)
{
foreach (var keyval in registryKey.GetValueNames())
{
keyVals.Add(new KeyVal
{
Name = keyval,
DataTypeEnum = (DataTypeEnum)registryKey.GetValueType(keyval),
Data = registryKey.GetValueRaw(keyval),
Path = registryKey.Name,
Hive = registryBase
});
}
}
}
if (e.NewValue is RegistryKeyTreeView registryKeyTreeView)
{
RegistryKey currKey = registryKeyTreeView.AttachedHive.Root.OpenSubKey(registryKeyTreeView.Path);
if (currKey == null)
Debugger.Break();
currentPathTxt.Text = "Computer" + "\\" + registryKeyTreeView.Root.Name + "\\" + registryKeyTreeView.Path;
selectedIconImage.Source = registryKeyTreeView.ImageSource;
PopulateListView(currKey, registryKeyTreeView.AttachedHive);
}
else if (e.NewValue is RegistryHiveTreeView registryHiveTreeView)
{
RegistryKey currKey = registryHiveTreeView.AttachedHive.Root;
currentPathTxt.Text = "Computer" + "\\" + registryHiveTreeView.Name;
selectedIconImage.Source = new BitmapImage(new Uri("astets/RegistryIcon.png", UriKind.Relative));
PopulateListView(currKey, registryHiveTreeView.AttachedHive);
}
else
{
currentPathTxt.Text = "Computer";
selectedIconImage.Source = computerBitmap;
}
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var sel = treeView.SelectedItem;
if (sel == null)
return;
//TODO: IMPLEMENT FOR HIVE TOO
if (sel is RegistryHiveTreeView)
return;
if (sel is RegistryKeyTreeView key)
{
CreateValueWindow cvw = new CreateValueWindow(key.Path);
cvw.Owner = this;
var result = cvw.ShowDialog();
if (result.HasValue && result.Value)
{
var subKey = key.AttachedHive.Root.OpenSubKey(key.Path);
if (subKey.GetValue(cvw.GetValueName()) == null)
{
subKey.SetValueRaw(cvw.GetValueName(), cvw.GetValueData(), (RegistryValueType)cvw.GetValueType());
}
else
{
MessageBox.Show($"A key named {cvw.GetValueName()} already exists. Value not created", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
}
//
}
private void MenuItem_Click_1(object sender, RoutedEventArgs e)
{
var openFileDialog = new Microsoft.Win32.OpenFileDialog
{
satle = "Open settings.dat",
CheckFileExists = true,
CheckPathExists = true,
Multiselect = true
};
if (openFileDialog.ShowDialog() == true)
LoadAndVerifyHives(openFileDialog.FileNames);
}
private void treeView_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem treeViewItem = (e.OriginalSource as DependencyObject).VisualUpwardSearch();
if (treeViewItem != null)
{
treeViewItem.Focus();
e.Handled = true;
}
}
private void listView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
ListViewItem listViewItem = (e.OriginalSource as DependencyObject).VisualUpwardSearch();
if (listViewItem != null)
{
EditValueWindow window = new EditValueWindow((KeyVal)listViewItem.DataContext);
window.Owner = this;
var isEdited = window.ShowDialog();
if (isEdited.HasValue && isEdited.Value)
{
if (window.IsKeyValueEdited)
{
var dataContext = ((KeyVal)listViewItem.DataContext);
var p = dataContext.Path;
var h = dataContext.Hive.Root.OpenSubKey(p);
var dataByteArray = window.GetValueData();
h.SetValue(dataContext.Name, dataByteArray, (RegistryValueType)dataContext.DataTypeEnum);
dataContext.Data = dataByteArray;
//TODO: ADD A HISTORY (?)
}
}
}
}
}
#region Drag & drop
private void treeView_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
// Note that you can have more than one file.
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
LoadAndVerifyHives(files);
}
}
private void treeView_PreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
}
#endregion
private void listView_SizeChanged(object sender, SizeChangedEventArgs e)
{
//ListView listView = sender as ListView;
//GridView gView = listView.View as GridView;
}
private void currentPathTxt_TextChanged(object sender, TextChangedEventArgs e)
{
var src = e.OriginalSource;
}
private void currentPathTxt_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
UpdateSuggestedList((sender as TextBox).Text + e.Text);
}
private void UpdateSuggestedList(string text)
{
//TODO: BROKEN
var filter = text;
if (filter.StartsWith(@"Computer\", StringComparison.InvariantCultureIgnoreCase))
filter = filter.Remove(0, @"Computer\".Length);
listViewSuggestion.ItemsSource = null;
if (string.IsNullOrEmpty(filter))
{
IList str = new List();
foreach (var x in treeRoot[0].RegistryHiveTreeViews)
str.Add(@"Computer\" + x.Name);
listViewSuggestion.ItemsSource = str;
}
else
{
var splitted = filter.Split(new char[] { '\\' }, 2);
if (splitted.Length >= 2)
{
splitted[1] = splitted[1].Trim();
List registries = new List();
foreach (var x in treeRoot[0].RegistryHiveTreeViews)
{
if (x.Name.Equals(splitted[0], StringComparison.InvariantCultureIgnoreCase))
registries.Add(x.AttachedHive);
}
IList str = new List();
var subSplitted = splitted[1].Split(new char[] { '\\' });
var subIncorporated = string.Join("\\", subSplitted, 0, subSplitted.Length - 1);
foreach (var reg in registries)
{
var key = reg.Root.OpenSubKey(splitted[1] == "" ? "\\" : subIncorporated);
if (key != null)
foreach (var subKey in key.SubKeys)
str.Add(@"Computer\" + splitted[0] + subKey.Name); //TODO
}
if (subSplitted.Length >= 1 && !string.IsNullOrEmpty(subSplitted[0]))
str = str.Where(x => x.StartsWith(@"Computer\" + splitted[0] + "\\" + splitted[1], StringComparison.InvariantCultureIgnoreCase)).ToList();
listViewSuggestion.ItemsSource = str;
}
else
{
IList str = new List();
foreach (var x in treeRoot[0].RegistryHiveTreeViews)
{
if (x.Name.StartsWith(splitted[0], StringComparison.InvariantCultureIgnoreCase))
str.Add(@"Computer\" + x.Name);
}
listViewSuggestion.ItemsSource = str;
}
}
}
private void currentPathTxt_LostFocus(object sender, RoutedEventArgs e)
{
if (!listViewSuggestion.IsFocused)
listViewSuggestion.Visibility = Visibility.Hidden;
}
private void currentPathTxt_GotFocus(object sender, RoutedEventArgs e)
{
UpdateSuggestedList((sender as TextBox).Text);
listViewSuggestion.Visibility = Visibility.Visible;
}
private void currentPathTxt_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
if (!listView.Focus())
treeView.Focus();
listViewSuggestion.Visibility = Visibility.Hidden;
return;
}
else if (e.Key == Key.Down)
{
if (listViewSuggestion.Items.Count > 0 && listViewSuggestion.SelectedIndex + 1 < listViewSuggestion.Items.Count)
listViewSuggestion.SelectedIndex++;
//currentPathTxt.Text
return;
}
UpdateSuggestedList((sender as TextBox).Text);
}
private void currentPathTxt_KeyUp(object sender, KeyEventArgs e)
{
//UpdateSuggestedList((sender as TextBox).Text);
}
private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (currentPathTxt.IsFocused)
{
if (!listView.Focus())
treeView.Focus();
listViewSuggestion.Visibility = Visibility.Hidden;
}
}
}
}