607 lines
15 KiB
C#
607 lines
15 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Security;
|
|
using System.Threading;
|
|
|
|
namespace Microsoft.Win32
|
|
{
|
|
// Token: 0x0200007A RID: 122
|
|
internal class KeyHandler
|
|
{
|
|
// Token: 0x06000737 RID: 1847 RVA: 0x00015FAC File Offset: 0x000141AC
|
|
private KeyHandler(RegistryKey rkey, string basedir)
|
|
{
|
|
if (!Directory.Exists(basedir))
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(basedir);
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
throw new SecurityException("No access to the given key");
|
|
}
|
|
}
|
|
this.Dir = basedir;
|
|
this.file = Path.Combine(this.Dir, "values.xml");
|
|
this.Load();
|
|
}
|
|
|
|
// Token: 0x06000739 RID: 1849 RVA: 0x00016048 File Offset: 0x00014248
|
|
public void Load()
|
|
{
|
|
this.values = new Hashtable();
|
|
if (!File.Exists(this.file))
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
using (FileStream fileStream = File.OpenRead(this.file))
|
|
{
|
|
StreamReader streamReader = new StreamReader(fileStream);
|
|
string text = streamReader.ReadToEnd();
|
|
if (text.Length != 0)
|
|
{
|
|
SecurityElement securityElement = SecurityElement.FromString(text);
|
|
if (securityElement.Tag == "values" && securityElement.Children != null)
|
|
{
|
|
foreach (object obj in securityElement.Children)
|
|
{
|
|
SecurityElement securityElement2 = (SecurityElement)obj;
|
|
if (securityElement2.Tag == "value")
|
|
{
|
|
this.LoadKey(securityElement2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
this.values.Clear();
|
|
throw new SecurityException("No access to the given key");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine("While loading registry key at {0}: {1}", this.file, ex);
|
|
this.values.Clear();
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600073A RID: 1850 RVA: 0x000161E8 File Offset: 0x000143E8
|
|
private void LoadKey(SecurityElement se)
|
|
{
|
|
Hashtable attributes = se.Attributes;
|
|
try
|
|
{
|
|
string text = (string)attributes["name"];
|
|
if (text != null)
|
|
{
|
|
string text2 = (string)attributes["type"];
|
|
if (text2 != null)
|
|
{
|
|
string text3 = text2;
|
|
switch (text3)
|
|
{
|
|
case "int":
|
|
this.values[text] = int.Parse(se.Text);
|
|
break;
|
|
case "bytearray":
|
|
this.values[text] = Convert.FromBase64String(se.Text);
|
|
break;
|
|
case "string":
|
|
this.values[text] = se.Text;
|
|
break;
|
|
case "expand":
|
|
this.values[text] = new ExpandString(se.Text);
|
|
break;
|
|
case "qword":
|
|
this.values[text] = long.Parse(se.Text);
|
|
break;
|
|
case "string-array":
|
|
{
|
|
ArrayList arrayList = new ArrayList();
|
|
if (se.Children != null)
|
|
{
|
|
foreach (object obj in se.Children)
|
|
{
|
|
SecurityElement securityElement = (SecurityElement)obj;
|
|
arrayList.Add(securityElement.Text);
|
|
}
|
|
}
|
|
this.values[text] = arrayList.ToArray(typeof(string));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600073B RID: 1851 RVA: 0x00016434 File Offset: 0x00014634
|
|
public RegistryKey Ensure(RegistryKey rkey, string extra, bool writable)
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
RegistryKey registryKey2;
|
|
lock (typeFromHandle)
|
|
{
|
|
string text = Path.Combine(this.Dir, extra);
|
|
KeyHandler keyHandler = (KeyHandler)KeyHandler.dir_to_handler[text];
|
|
if (keyHandler == null)
|
|
{
|
|
keyHandler = new KeyHandler(rkey, text);
|
|
}
|
|
RegistryKey registryKey = new RegistryKey(keyHandler, KeyHandler.CombineName(rkey, extra), writable);
|
|
KeyHandler.key_to_handler[registryKey] = keyHandler;
|
|
KeyHandler.dir_to_handler[text] = keyHandler;
|
|
registryKey2 = registryKey;
|
|
}
|
|
return registryKey2;
|
|
}
|
|
|
|
// Token: 0x0600073C RID: 1852 RVA: 0x000164D8 File Offset: 0x000146D8
|
|
public RegistryKey Probe(RegistryKey rkey, string extra, bool writable)
|
|
{
|
|
RegistryKey registryKey = null;
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
RegistryKey registryKey2;
|
|
lock (typeFromHandle)
|
|
{
|
|
string text = Path.Combine(this.Dir, extra);
|
|
KeyHandler keyHandler = (KeyHandler)KeyHandler.dir_to_handler[text];
|
|
if (keyHandler != null)
|
|
{
|
|
registryKey = new RegistryKey(keyHandler, KeyHandler.CombineName(rkey, extra), writable);
|
|
KeyHandler.key_to_handler[registryKey] = keyHandler;
|
|
}
|
|
else if (Directory.Exists(text))
|
|
{
|
|
keyHandler = new KeyHandler(rkey, text);
|
|
registryKey = new RegistryKey(keyHandler, KeyHandler.CombineName(rkey, extra), writable);
|
|
KeyHandler.dir_to_handler[text] = keyHandler;
|
|
KeyHandler.key_to_handler[registryKey] = keyHandler;
|
|
}
|
|
registryKey2 = registryKey;
|
|
}
|
|
return registryKey2;
|
|
}
|
|
|
|
// Token: 0x0600073D RID: 1853 RVA: 0x000165A8 File Offset: 0x000147A8
|
|
private static string CombineName(RegistryKey rkey, string extra)
|
|
{
|
|
if (extra.IndexOf('/') != -1)
|
|
{
|
|
extra = extra.Replace('/', '\\');
|
|
}
|
|
return rkey.Name + "\\" + extra;
|
|
}
|
|
|
|
// Token: 0x0600073E RID: 1854 RVA: 0x000165E0 File Offset: 0x000147E0
|
|
public static KeyHandler Lookup(RegistryKey rkey, bool createNonExisting)
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
KeyHandler keyHandler2;
|
|
lock (typeFromHandle)
|
|
{
|
|
KeyHandler keyHandler = (KeyHandler)KeyHandler.key_to_handler[rkey];
|
|
if (keyHandler != null)
|
|
{
|
|
keyHandler2 = keyHandler;
|
|
}
|
|
else if (!rkey.IsRoot || !createNonExisting)
|
|
{
|
|
keyHandler2 = null;
|
|
}
|
|
else
|
|
{
|
|
RegistryHive hive = rkey.Hive;
|
|
RegistryHive registryHive = hive;
|
|
switch (registryHive + -2147483648)
|
|
{
|
|
case (RegistryHive)0:
|
|
case (RegistryHive)2:
|
|
case (RegistryHive)3:
|
|
case (RegistryHive)4:
|
|
case (RegistryHive)5:
|
|
case (RegistryHive)6:
|
|
{
|
|
string text = Path.Combine(KeyHandler.MachineStore, hive.ToString());
|
|
keyHandler = new KeyHandler(rkey, text);
|
|
KeyHandler.dir_to_handler[text] = keyHandler;
|
|
break;
|
|
}
|
|
case (RegistryHive)1:
|
|
{
|
|
string text2 = Path.Combine(KeyHandler.UserStore, hive.ToString());
|
|
keyHandler = new KeyHandler(rkey, text2);
|
|
KeyHandler.dir_to_handler[text2] = keyHandler;
|
|
break;
|
|
}
|
|
default:
|
|
throw new Exception("Unknown RegistryHive");
|
|
}
|
|
KeyHandler.key_to_handler[rkey] = keyHandler;
|
|
keyHandler2 = keyHandler;
|
|
}
|
|
}
|
|
return keyHandler2;
|
|
}
|
|
|
|
// Token: 0x0600073F RID: 1855 RVA: 0x00016718 File Offset: 0x00014918
|
|
public static void Drop(RegistryKey rkey)
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
lock (typeFromHandle)
|
|
{
|
|
KeyHandler keyHandler = (KeyHandler)KeyHandler.key_to_handler[rkey];
|
|
if (keyHandler != null)
|
|
{
|
|
KeyHandler.key_to_handler.Remove(rkey);
|
|
int num = 0;
|
|
foreach (object obj in KeyHandler.key_to_handler)
|
|
{
|
|
if (((DictionaryEntry)obj).Value == keyHandler)
|
|
{
|
|
num++;
|
|
}
|
|
}
|
|
if (num == 0)
|
|
{
|
|
KeyHandler.dir_to_handler.Remove(keyHandler.Dir);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000740 RID: 1856 RVA: 0x0001680C File Offset: 0x00014A0C
|
|
public static void Drop(string dir)
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
lock (typeFromHandle)
|
|
{
|
|
KeyHandler keyHandler = (KeyHandler)KeyHandler.dir_to_handler[dir];
|
|
if (keyHandler != null)
|
|
{
|
|
KeyHandler.dir_to_handler.Remove(dir);
|
|
ArrayList arrayList = new ArrayList();
|
|
foreach (object obj in KeyHandler.key_to_handler)
|
|
{
|
|
DictionaryEntry dictionaryEntry = (DictionaryEntry)obj;
|
|
if (dictionaryEntry.Value == keyHandler)
|
|
{
|
|
arrayList.Add(dictionaryEntry.Key);
|
|
}
|
|
}
|
|
foreach (object obj2 in arrayList)
|
|
{
|
|
KeyHandler.key_to_handler.Remove(obj2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000741 RID: 1857 RVA: 0x00016958 File Offset: 0x00014B58
|
|
public object GetValue(string name, RegistryValueOptions options)
|
|
{
|
|
if (this.IsMarkedForDeletion)
|
|
{
|
|
return null;
|
|
}
|
|
if (name == null)
|
|
{
|
|
name = string.Empty;
|
|
}
|
|
object obj = this.values[name];
|
|
ExpandString expandString = obj as ExpandString;
|
|
if (expandString == null)
|
|
{
|
|
return obj;
|
|
}
|
|
if ((options & RegistryValueOptions.DoNotExpandEnvironmentNames) == RegistryValueOptions.None)
|
|
{
|
|
return expandString.Expand();
|
|
}
|
|
return expandString.ToString();
|
|
}
|
|
|
|
// Token: 0x06000742 RID: 1858 RVA: 0x000169B0 File Offset: 0x00014BB0
|
|
public void SetValue(string name, object value)
|
|
{
|
|
this.AssertNotMarkedForDeletion();
|
|
if (name == null)
|
|
{
|
|
name = string.Empty;
|
|
}
|
|
if (value is int || value is string || value is byte[] || value is string[])
|
|
{
|
|
this.values[name] = value;
|
|
}
|
|
else
|
|
{
|
|
this.values[name] = value.ToString();
|
|
}
|
|
this.SetDirty();
|
|
}
|
|
|
|
// Token: 0x06000743 RID: 1859 RVA: 0x00016A28 File Offset: 0x00014C28
|
|
public string[] GetValueNames()
|
|
{
|
|
this.AssertNotMarkedForDeletion();
|
|
ICollection keys = this.values.Keys;
|
|
string[] array = new string[keys.Count];
|
|
keys.CopyTo(array, 0);
|
|
return array;
|
|
}
|
|
|
|
// Token: 0x06000744 RID: 1860 RVA: 0x00016A5C File Offset: 0x00014C5C
|
|
public void SetValue(string name, object value, RegistryValueKind valueKind)
|
|
{
|
|
this.SetDirty();
|
|
if (name == null)
|
|
{
|
|
name = string.Empty;
|
|
}
|
|
switch (valueKind)
|
|
{
|
|
case RegistryValueKind.String:
|
|
if (value is string)
|
|
{
|
|
this.values[name] = value;
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
case RegistryValueKind.ExpandString:
|
|
if (value is string)
|
|
{
|
|
this.values[name] = new ExpandString((string)value);
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
case RegistryValueKind.Binary:
|
|
if (value is byte[])
|
|
{
|
|
this.values[name] = value;
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
case RegistryValueKind.DWord:
|
|
if (value is long && (long)value < 2147483647L && (long)value > -2147483648L)
|
|
{
|
|
this.values[name] = (int)((long)value);
|
|
return;
|
|
}
|
|
if (value is int)
|
|
{
|
|
this.values[name] = value;
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
case RegistryValueKind.MultiString:
|
|
if (value is string[])
|
|
{
|
|
this.values[name] = value;
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
case RegistryValueKind.QWord:
|
|
if (value is int)
|
|
{
|
|
this.values[name] = (long)((int)value);
|
|
return;
|
|
}
|
|
if (value is long)
|
|
{
|
|
this.values[name] = value;
|
|
return;
|
|
}
|
|
goto IL_186;
|
|
}
|
|
throw new ArgumentException("unknown value", "valueKind");
|
|
IL_186:
|
|
throw new ArgumentException("Value could not be converted to specified type", "valueKind");
|
|
}
|
|
|
|
// Token: 0x06000745 RID: 1861 RVA: 0x00016C00 File Offset: 0x00014E00
|
|
private void SetDirty()
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
lock (typeFromHandle)
|
|
{
|
|
if (!this.dirty)
|
|
{
|
|
this.dirty = true;
|
|
new Timer(new TimerCallback(this.DirtyTimeout), null, 3000, -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000746 RID: 1862 RVA: 0x00016C78 File Offset: 0x00014E78
|
|
public void DirtyTimeout(object state)
|
|
{
|
|
this.Flush();
|
|
}
|
|
|
|
// Token: 0x06000747 RID: 1863 RVA: 0x00016C80 File Offset: 0x00014E80
|
|
public void Flush()
|
|
{
|
|
Type typeFromHandle = typeof(KeyHandler);
|
|
lock (typeFromHandle)
|
|
{
|
|
if (this.dirty)
|
|
{
|
|
this.Save();
|
|
this.dirty = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000748 RID: 1864 RVA: 0x00016CE0 File Offset: 0x00014EE0
|
|
public bool ValueExists(string name)
|
|
{
|
|
if (name == null)
|
|
{
|
|
name = string.Empty;
|
|
}
|
|
return this.values.Contains(name);
|
|
}
|
|
|
|
// Token: 0x170000D8 RID: 216
|
|
// (get) Token: 0x06000749 RID: 1865 RVA: 0x00016CFC File Offset: 0x00014EFC
|
|
public int ValueCount
|
|
{
|
|
get
|
|
{
|
|
return this.values.Keys.Count;
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000D9 RID: 217
|
|
// (get) Token: 0x0600074A RID: 1866 RVA: 0x00016D10 File Offset: 0x00014F10
|
|
public bool IsMarkedForDeletion
|
|
{
|
|
get
|
|
{
|
|
return !KeyHandler.dir_to_handler.Contains(this.Dir);
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600074B RID: 1867 RVA: 0x00016D28 File Offset: 0x00014F28
|
|
public void RemoveValue(string name)
|
|
{
|
|
this.AssertNotMarkedForDeletion();
|
|
this.values.Remove(name);
|
|
this.SetDirty();
|
|
}
|
|
|
|
// Token: 0x0600074C RID: 1868 RVA: 0x00016D50 File Offset: 0x00014F50
|
|
~KeyHandler()
|
|
{
|
|
this.Flush();
|
|
}
|
|
|
|
// Token: 0x0600074D RID: 1869 RVA: 0x00016D8C File Offset: 0x00014F8C
|
|
private void Save()
|
|
{
|
|
if (this.IsMarkedForDeletion)
|
|
{
|
|
return;
|
|
}
|
|
if (!File.Exists(this.file) && this.values.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
SecurityElement securityElement = new SecurityElement("values");
|
|
foreach (object obj in this.values)
|
|
{
|
|
DictionaryEntry dictionaryEntry = (DictionaryEntry)obj;
|
|
object value = dictionaryEntry.Value;
|
|
SecurityElement securityElement2 = new SecurityElement("value");
|
|
securityElement2.AddAttribute("name", SecurityElement.Escape((string)dictionaryEntry.Key));
|
|
if (value is string)
|
|
{
|
|
securityElement2.AddAttribute("type", "string");
|
|
securityElement2.Text = SecurityElement.Escape((string)value);
|
|
}
|
|
else if (value is int)
|
|
{
|
|
securityElement2.AddAttribute("type", "int");
|
|
securityElement2.Text = value.ToString();
|
|
}
|
|
else if (value is long)
|
|
{
|
|
securityElement2.AddAttribute("type", "qword");
|
|
securityElement2.Text = value.ToString();
|
|
}
|
|
else if (value is byte[])
|
|
{
|
|
securityElement2.AddAttribute("type", "bytearray");
|
|
securityElement2.Text = Convert.ToBase64String((byte[])value);
|
|
}
|
|
else if (value is ExpandString)
|
|
{
|
|
securityElement2.AddAttribute("type", "expand");
|
|
securityElement2.Text = SecurityElement.Escape(value.ToString());
|
|
}
|
|
else if (value is string[])
|
|
{
|
|
securityElement2.AddAttribute("type", "string-array");
|
|
foreach (string text in (string[])value)
|
|
{
|
|
securityElement2.AddChild(new SecurityElement("string")
|
|
{
|
|
Text = SecurityElement.Escape(text)
|
|
});
|
|
}
|
|
}
|
|
securityElement.AddChild(securityElement2);
|
|
}
|
|
using (FileStream fileStream = File.Create(this.file))
|
|
{
|
|
StreamWriter streamWriter = new StreamWriter(fileStream);
|
|
streamWriter.Write(securityElement.ToString());
|
|
streamWriter.Flush();
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600074E RID: 1870 RVA: 0x0001701C File Offset: 0x0001521C
|
|
private void AssertNotMarkedForDeletion()
|
|
{
|
|
if (this.IsMarkedForDeletion)
|
|
{
|
|
throw RegistryKey.CreateMarkedForDeletionException();
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000DA RID: 218
|
|
// (get) Token: 0x0600074F RID: 1871 RVA: 0x00017030 File Offset: 0x00015230
|
|
private static string UserStore
|
|
{
|
|
get
|
|
{
|
|
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), ".mono/registry");
|
|
}
|
|
}
|
|
|
|
// Token: 0x170000DB RID: 219
|
|
// (get) Token: 0x06000750 RID: 1872 RVA: 0x00017044 File Offset: 0x00015244
|
|
private static string MachineStore
|
|
{
|
|
get
|
|
{
|
|
string text = Environment.GetEnvironmentVariable("MONO_REGISTRY_PATH");
|
|
if (text != null)
|
|
{
|
|
return text;
|
|
}
|
|
text = Environment.GetMachineConfigPath();
|
|
int num = text.IndexOf("machine.config");
|
|
return Path.Combine(Path.Combine(text.Substring(0, num - 1), ".."), "registry");
|
|
}
|
|
}
|
|
|
|
// Token: 0x04000102 RID: 258
|
|
private static Hashtable key_to_handler = new Hashtable();
|
|
|
|
// Token: 0x04000103 RID: 259
|
|
private static Hashtable dir_to_handler = new Hashtable(new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer());
|
|
|
|
// Token: 0x04000104 RID: 260
|
|
public string Dir;
|
|
|
|
// Token: 0x04000105 RID: 261
|
|
private Hashtable values;
|
|
|
|
// Token: 0x04000106 RID: 262
|
|
private string file;
|
|
|
|
// Token: 0x04000107 RID: 263
|
|
private bool dirty;
|
|
}
|
|
}
|