[Test] Avoid MethodInfoTest.GetMethodBody failure when executed on a release (IL...
[mono.git] / mcs / class / corlib / Microsoft.Win32 / RegistryKey.cs
index 3d47468fffc60eafe6d5698ac95e38784762e955..2d742a6ee9385007de91fb0778d6a17ee4953dd6 100644 (file)
@@ -29,6 +29,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#if !NET_2_1
+
 using System;
 using System.IO;
 using System.Collections;
@@ -36,12 +38,16 @@ using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Text;
+using System.Security.AccessControl;
+using System.Security.Permissions;
+using Microsoft.Win32.SafeHandles;
 
 namespace Microsoft.Win32
 {
        /// <summary>
        ///     Wrapper class for Windows Registry Entry.
        /// </summary>
+       [ComVisible (true)]
        public sealed class RegistryKey : MarshalByRefObject, IDisposable 
        {
                //
@@ -49,6 +55,9 @@ namespace Microsoft.Win32
                // RegistryKey object
                //
                object handle;
+#if NET_4_0
+               SafeRegistryHandle safe_handle;
+#endif
 
                object hive; // the RegistryHive if the key represents a base key
                readonly string qname;  // the fully qualified registry key name
@@ -101,7 +110,11 @@ namespace Microsoft.Win32
                ///     Dispose of registry key object. Close the 
                ///     key if it's still open.
                /// </summary>
+#if NET_4_0
+               public void Dispose ()
+#else
                void IDisposable.Dispose ()
+#endif
                {
                        GC.SuppressFinalize (this);
                        Close ();
@@ -150,6 +163,9 @@ namespace Microsoft.Win32
                        
                        RegistryApi.Close (this);
                        handle = null;
+#if NET_4_0
+                       safe_handle = null;
+#endif
                }
                
                
@@ -176,6 +192,31 @@ namespace Microsoft.Win32
                        }
                }
 
+#if NET_4_0
+               [ComVisible (false)]
+               [MonoTODO ("Not implemented in Unix")]
+               public SafeRegistryHandle Handle {
+                       get {
+                               AssertKeyStillValid ();
+
+                               if (safe_handle == null) {
+                                       IntPtr h = RegistryApi.GetHandle (this);
+                                       safe_handle = new SafeRegistryHandle (h, true);
+                               }
+
+                               return safe_handle;
+                       }
+               }
+
+               [ComVisible (false)]
+               [MonoLimitation ("View is ignored in Mono.")]
+               public RegistryView View {
+                       get {
+                               return RegistryView.Default;
+                       }
+               }
+#endif
+
                
                /// <summary>
                ///     Set a registry value.
@@ -187,46 +228,54 @@ namespace Microsoft.Win32
                        if (value == null)
                                throw new ArgumentNullException ("value");
 
+                       if (name != null)
+                               AssertKeyNameLength (name);
+
                        if (!IsWritable)
                                throw new UnauthorizedAccessException ("Cannot write to the registry key.");
 
                        RegistryApi.SetValue (this, name, value);
                }
 
-#if NET_2_0
                [ComVisible (false)]
                public void SetValue (string name, object value, RegistryValueKind valueKind)
                {
                        AssertKeyStillValid ();
                        
                        if (value == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("value");
+
+                       if (name != null)
+                               AssertKeyNameLength (name);
 
                        if (!IsWritable)
                                throw new UnauthorizedAccessException ("Cannot write to the registry key.");
 
                        RegistryApi.SetValue (this, name, value, valueKind);
                }
-#endif
 
                /// <summary>
                ///     Open the sub key specified, for read access.
                /// </summary>
-               public RegistryKey OpenSubKey (string keyName)
+               public RegistryKey OpenSubKey (string name)
                {
-                       return OpenSubKey (keyName, false);
+                       return OpenSubKey (name, false);
                }
 
                
                /// <summary>
                ///     Open the sub key specified.
                /// </summary>
-               public RegistryKey OpenSubKey (string keyName, bool writtable)
+               public RegistryKey OpenSubKey (string name, bool writable)
                {
                        AssertKeyStillValid ();
-                       AssertKeyNameNotNull (keyName);
 
-                       return RegistryApi.OpenSubKey (this, keyName, writtable);
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+
+                       AssertKeyNameLength (name);
+
+                       return RegistryApi.OpenSubKey (this, name, writable);
                }
                
                
@@ -250,7 +299,6 @@ namespace Microsoft.Win32
                                RegistryValueOptions.None);
                }
 
-#if NET_2_0
                [ComVisible (false)]
                public object GetValue (string name, object defaultValue, RegistryValueOptions options)
                {
@@ -258,24 +306,65 @@ namespace Microsoft.Win32
 
                        return RegistryApi.GetValue (this, name, defaultValue, options);
                }
-#endif
+
+               [ComVisible (false)]
+               public RegistryValueKind GetValueKind (string name)
+               {
+                       return RegistryApi.GetValueKind (this, name);
+               }
 
                /// <summary>
                ///     Create a sub key.
                /// </summary>
-               [MonoTODO("RegistryPermission")]
                public RegistryKey CreateSubKey (string subkey)
                {
                        AssertKeyStillValid ();
                        AssertKeyNameNotNull (subkey);
-                       if (subkey.Length > 255)
-                               throw new ArgumentException ("keyName length is larger than 255 characters", subkey);
+                       AssertKeyNameLength (subkey);
 
                        if (!IsWritable)
                                throw new UnauthorizedAccessException ("Cannot write to the registry key.");
                        return RegistryApi.CreateSubKey (this, subkey);
                }
-               
+
+               [ComVisible (false)]
+               [MonoLimitation ("permissionCheck is ignored in Mono")]
+               public RegistryKey CreateSubKey (string subkey, RegistryKeyPermissionCheck permissionCheck)
+               {
+                       return CreateSubKey (subkey);
+               }
+
+               [ComVisible (false)]
+               [MonoLimitation ("permissionCheck and registrySecurity are ignored in Mono")]
+               public RegistryKey CreateSubKey (string subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity)
+               {
+                       return CreateSubKey (subkey);
+               }
+
+#if NET_4_0
+               [ComVisible (false)]
+               [MonoLimitation ("permissionCheck is ignored in Mono")]
+               public RegistryKey CreateSubKey (string subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions options)
+               {
+                       AssertKeyStillValid ();
+                       AssertKeyNameNotNull (subkey);
+                       AssertKeyNameLength (subkey);
+
+                       if (!IsWritable)
+                               throw new UnauthorizedAccessException ("Cannot write to the registry key.");
+
+                       return RegistryApi.CreateSubKey (this, subkey, options);
+               }
+
+               [ComVisible (false)]
+               [MonoLimitation ("permissionCheck and registrySecurity are ignored in Mono")]
+               public RegistryKey CreateSubKey (string subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions registryOptions,
+                       RegistrySecurity registrySecurity)
+               {
+                       return CreateSubKey (subkey, permissionCheck, registryOptions);
+               }
+#endif
+
                
                /// <summary>
                ///     Delete the specified subkey.
@@ -293,6 +382,7 @@ namespace Microsoft.Win32
                {
                        AssertKeyStillValid ();
                        AssertKeyNameNotNull (subkey);
+                       AssertKeyNameLength (subkey);
 
                        if (!IsWritable)
                                throw new UnauthorizedAccessException ("Cannot write to the registry key.");
@@ -320,47 +410,74 @@ namespace Microsoft.Win32
                /// <summary>
                ///     Delete a sub tree (node, and values alike).
                /// </summary>
-               public void DeleteSubKeyTree(string keyName)
+               public void DeleteSubKeyTree(string subkey)
+               {
+                       DeleteSubKeyTree (subkey, true);
+               }
+
+#if NET_4_0
+               public
+#endif
+               void DeleteSubKeyTree (string subkey, bool throwOnMissingSubKey)
                {
                        // Note: this is done by deleting sub-nodes recursively.
                        // The preformance is not very good. There may be a 
                        // better way to implement this.
                        
                        AssertKeyStillValid ();
-                       AssertKeyNameNotNull (keyName);
+                       AssertKeyNameNotNull (subkey);
+                       AssertKeyNameLength (subkey);
                        
-                       RegistryKey child = OpenSubKey (keyName, true);
-                       if (child == null)
+                       RegistryKey child = OpenSubKey (subkey, true);
+                       if (child == null) {
+                               if (!throwOnMissingSubKey)
+                                       return;
+
                                throw new ArgumentException ("Cannot delete a subkey tree"
                                        + " because the subkey does not exist.");
+                       }
 
                        child.DeleteChildKeysAndValues ();
                        child.Close ();
-                       DeleteSubKey (keyName, false);
+                       DeleteSubKey (subkey, false);
                }
                
 
                /// <summary>
                ///     Delete a value from the registry.
                /// </summary>
-               public void DeleteValue(string value)
+               public void DeleteValue(string name)
                {
-                       DeleteValue (value, true);
+                       DeleteValue (name, true);
                }
                
                
                /// <summary>
                ///     Delete a value from the registry.
                /// </summary>
-               public void DeleteValue(string value, bool shouldThrowWhenKeyMissing)
+               public void DeleteValue(string name, bool throwOnMissingValue)
                {
                        AssertKeyStillValid ();
-                       AssertKeyNameNotNull (value);
+
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
 
                        if (!IsWritable)
                                throw new UnauthorizedAccessException ("Cannot write to the registry key.");
 
-                       RegistryApi.DeleteValue (this, value, shouldThrowWhenKeyMissing);
+                       RegistryApi.DeleteValue (this, name, throwOnMissingValue);
+               }
+
+               public RegistrySecurity GetAccessControl ()
+               {
+                       return GetAccessControl (AccessControlSections.Owner |
+                                                AccessControlSections.Group |
+                                                AccessControlSections.Access);
+               }
+               
+               public RegistrySecurity GetAccessControl (AccessControlSections includeSections)
+               {
+                       return new RegistrySecurity (Name, includeSections);
                }
                
                
@@ -383,6 +500,27 @@ namespace Microsoft.Win32
                        AssertKeyStillValid ();
                        return RegistryApi.GetValueNames (this);
                }
+
+#if NET_4_0
+               [ComVisible (false)]
+               [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+               [MonoTODO ("Not implemented on unix")]
+               public static RegistryKey FromHandle (SafeRegistryHandle handle)
+               {
+                       if (handle == null)
+                               throw new ArgumentNullException ("handle");
+
+                       return RegistryApi.FromHandle (handle);
+               }
+
+               [ComVisible (false)]
+               [SecurityPermission (SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+               [MonoTODO ("Not implemented on unix")]
+               public static RegistryKey FromHandle (SafeRegistryHandle handle, RegistryView view)
+               {
+                       return FromHandle (handle);
+               }
+#endif
                
                
                [MonoTODO ("Not implemented on unix")]
@@ -392,6 +530,62 @@ namespace Microsoft.Win32
                                throw new ArgumentNullException ("machineName");
                        return RegistryApi.OpenRemoteBaseKey (hKey, machineName);
                }
+
+#if NET_4_0
+               [ComVisible (false)]
+               [MonoTODO ("Not implemented on unix")]
+               public static RegistryKey OpenRemoteBaseKey (RegistryHive hKey, string machineName, RegistryView view)
+               {
+                       if (machineName == null)
+                               throw new ArgumentNullException ("machineName");
+                       return RegistryApi.OpenRemoteBaseKey (hKey, machineName);
+               }
+
+               [ComVisible (false)]
+               [MonoLimitation ("View is ignored in Mono")]
+               public static RegistryKey OpenBaseKey (RegistryHive hKey, RegistryView view)
+               {
+                       switch (hKey) {
+                               case RegistryHive.ClassesRoot:
+                                       return Registry.ClassesRoot;
+                               case RegistryHive.CurrentConfig:
+                                       return Registry.CurrentConfig;
+                               case RegistryHive.CurrentUser:
+                                       return Registry.CurrentUser;
+                               case RegistryHive.DynData:
+                                       return Registry.DynData;
+                               case RegistryHive.LocalMachine:
+                                       return Registry.LocalMachine;
+                               case RegistryHive.PerformanceData:
+                                       return Registry.PerformanceData;
+                               case RegistryHive.Users:
+                                       return Registry.Users;
+                       }
+
+                       throw new ArgumentException ("hKey");
+               }
+#endif
+
+               [ComVisible (false)]
+               public RegistryKey OpenSubKey (string name, RegistryKeyPermissionCheck permissionCheck)
+               {
+                       return OpenSubKey (name, permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree);
+               }
+               
+               [ComVisible (false)]
+               [MonoLimitation ("rights are ignored in Mono")]
+               public RegistryKey OpenSubKey (string name, RegistryKeyPermissionCheck permissionCheck, RegistryRights rights)
+               {
+                       return OpenSubKey (name, permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree);
+               }
+               
+               public void SetAccessControl (RegistrySecurity registrySecurity)
+               {
+                       if (null == registrySecurity)
+                               throw new ArgumentNullException ("registrySecurity");
+                               
+                       registrySecurity.PersistModifications (Name);
+               }
                
                
                /// <summary>
@@ -426,7 +620,7 @@ namespace Microsoft.Win32
 
                // returns the key handle for the win32 implementation and the
                // KeyHandler for the unix implementation
-               internal object Handle {
+               internal object InternalHandle {
                        get { return handle; }
                }
 
@@ -447,9 +641,14 @@ namespace Microsoft.Win32
                private void AssertKeyNameNotNull (string subKeyName)
                {
                        if (subKeyName == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("name");
+               }
+
+               private void AssertKeyNameLength (string name)
+               {
+                       if (name.Length > 255)
+                               throw new ArgumentException ("Name of registry key cannot be greater than 255 characters");
                }
-               
 
                /// <summary>
                ///     Utility method to delelte a key's sub keys and values.
@@ -520,3 +719,5 @@ namespace Microsoft.Win32
        }
 }
 
+#endif // NET_2_1
+