Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[mono.git] / mcs / class / corlib / Test / Microsoft.Win32 / RegistryKeyTest.cs
old mode 100644 (file)
new mode 100755 (executable)
index 7e1c7a5..7279f71
 
 using System;
 using System.IO;
+using System.Runtime.InteropServices;
 
 using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
 
 using NUnit.Framework;
 
@@ -42,7 +44,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // this test is for Windows only
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        // this regpath always exists under windows
                        RegistryKey k = Registry.CurrentUser
@@ -299,7 +301,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -389,7 +391,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -1107,6 +1109,27 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+#if NET_4_0
+               [Test]
+               public void DeleteSubKeyTree_Key_DoesNotExist_Overload ()
+               {
+                       // Cannot delete a subkey tree because the subkey does not exist
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName, true);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
+
+                       // It's enough to know this line is not throwing an exception.
+                       Registry.CurrentUser.DeleteSubKey (subKeyName, false);
+               }
+#endif
+
                [Test]
                public void DeleteSubKeyTree_Key_ReadOnly ()
                {
@@ -1228,11 +1251,7 @@ namespace MonoTests.Microsoft.Win32
                                        Assert.IsNull (createdKey, "#A2");
                                }
 
-#if ONLY_1_1
-                               subKeyName = new string ('a', 255);
-#else
                                subKeyName = new string ('a', 256);
-#endif
 
                                try {
                                        softwareKey.DeleteSubKeyTree (subKeyName);
@@ -1639,6 +1658,102 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+#if NET_4_0
+               [DllImport ("advapi32.dll", CharSet = CharSet.Unicode)]
+               static extern int RegOpenKeyEx (IntPtr keyBase, string keyName, IntPtr reserved, int access, out IntPtr keyHandle);
+        
+               const int RegCurrentUserHive = -2147483647;
+               const int RegAccessRead = 0x00020019;
+
+               // FromHandle is specially designed to retrieve a RegistryKey instance based on a IntPtr
+               // retrieved using any unmanaged registry function, so we use directly RegOpenKeyEx to load
+               // our handle and then pass it to the new 4.0 method.
+               [Test]
+               public void FromHandle ()
+               {
+                       // Not supported on Unix
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               using (RegistryKey key = Registry.CurrentUser.CreateSubKey (subKeyName))
+                                       key.SetValue ("Name", "Mono001");
+
+                               IntPtr handle;
+                               int res = RegOpenKeyEx (new IntPtr (RegCurrentUserHive), subKeyName, IntPtr.Zero, RegAccessRead, out handle);
+
+                               using (RegistryKey key = RegistryKey.FromHandle (new SafeRegistryHandle (handle, true))) {
+                                       Assert.AreEqual (String.Empty, key.Name, "#A0");
+                                       Assert.AreEqual ("Mono001", key.GetValue ("Name"), "#A1");
+                               }
+                       } finally {
+                               RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               if (createdKey != null) {
+                                       createdKey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                               }
+                       }
+               }
+
+               [Test]
+               public void FromHandle_InvalidHandle ()
+               {
+                       // Not supported on Unix
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               using (RegistryKey key = RegistryKey.FromHandle (new SafeRegistryHandle (IntPtr.Zero, true))) {
+                                       Assert.AreEqual (String.Empty, key.Name, "#A0");
+
+                                       // Any operation should throw a IOException, since even if we have a RegistryKey instance,
+                                       // the handle is not valid.
+                                       key.CreateSubKey ("ChildSubKey");
+                                       Assert.Fail ("#Exc0");
+                               }
+                       } catch (IOException) {
+                       } finally {
+                               RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               if (createdKey != null) {
+                                       createdKey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                               }
+                       }
+               }
+
+               [Test]
+               public void Handle ()
+               {
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       RegistryKey subkey = null;
+                       try {
+                               subkey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                               Assert.AreEqual (true, subkey.Handle != null, "#A0");
+                               Assert.AreEqual (false, subkey.Handle.IsClosed, "#A1");
+                               Assert.AreEqual (false, subkey.Handle.IsInvalid, "#A2");
+
+                               subkey.Close ();
+                               try {
+                                       if (subkey.Handle != null)
+                                               Console.WriteLine (); // Avoids a warning at compile time
+                                       Assert.Fail ("#Disposed");
+                               } catch (ObjectDisposedException) {
+                               }
+
+                       } finally {
+                               if (subkey != null) {
+                                       subkey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName, false);
+                               }
+                       }
+               }
+#endif
+
                [Test]
                public void GetValue ()
                {
@@ -2054,7 +2169,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -2082,11 +2197,13 @@ namespace MonoTests.Microsoft.Win32
                }
 
                [Test]
+               // This hangs on windows
+               [Category ("NotWorking")]
                public void OpenRemoteBaseKey_MachineName_DoesNotExist ()
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        try {
                                RegistryKey.OpenRemoteBaseKey (RegistryHive.CurrentUser,
@@ -3072,6 +3189,122 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               // Bug Xamarin 3632
+               [Test]
+               public void TypeCastTests ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               createdKey.SetValue ("test-int", (int) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-uint", (uint) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-byte", (byte) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-sbyte", (sbyte) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-short", (short) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-ushort", (ushort) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-long", (long) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-ulong", (ulong) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-decimal", (decimal) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-float", (float) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-bool", true, RegistryValueKind.DWord);
+
+                                               createdKey.SetValue ("dtest-int", (int) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-uint", (uint) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-byte", (byte) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-sbyte", (sbyte) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-short", (short) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-ushort", (ushort) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-long", (long) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-ulong", (ulong) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-decimal", (decimal) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-float", (float) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-bool", true, RegistryValueKind.QWord);
+
+                                               object r = createdKey.GetValue ("test-int");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               
+                                               r = createdKey.GetValue ("test-uint");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-byte");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-sbyte");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-short");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-ushort");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-long");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-ulong");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+
+                                               r = createdKey.GetValue ("dtest-int");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-uint");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-byte");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-sbyte");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-short");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-ushort");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-long");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-ulong");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-decimal");
+                                               Assert.IsTrue (r is long);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-float");
+                                               Assert.IsTrue (r is long);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-bool");
+                                               Assert.AreEqual (typeof (long), r.GetType ());
+
+                                               try {
+                                                       createdKey.SetValue ("test-int", uint.MaxValue, RegistryValueKind.DWord);
+                                                       Assert.Fail ("#100");
+
+                                                       createdKey.SetValue ("test-int", ulong.MaxValue, RegistryValueKind.QWord);
+                                                       Assert.Fail ("#101");
+                                               } catch (ArgumentException) {
+                                               }
+                                               
+                                               createdKey.Close ();
+                                               softwareKey.DeleteSubKeyTree (subKeyName);
+                                       }
+                               } finally {
+                                       try {
+                                               RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName);
+                                               if (createdKey != null) {
+                                                       createdKey.Close ();
+                                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                                               }
+                                       } catch {
+                                       }
+                               }
+                       }
+               }
+               
                [Test]
                public void bug79059 ()
                {