2009-07-30 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / corlib / Microsoft.Win32 / UnixRegistryApi.cs
index 5b6ff37be792b8767d0565d7021d1100bcbd2314..39d5d2e3bbc2f638f93062c27802bfe20800b272 100644 (file)
@@ -37,6 +37,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#if !NET_2_1
+
 using System;
 using System.Collections;
 using System.Globalization;
@@ -94,20 +96,20 @@ namespace Microsoft.Win32 {
                static Hashtable key_to_handler = new Hashtable ();
                static Hashtable dir_to_handler = new Hashtable (
                        new CaseInsensitiveHashCodeProvider (), new CaseInsensitiveComparer ());
-               /*
-                const string MACHINE_STORE_VAR = "MONO_REGISTRY_MACHINE";
-               */
-
                public string Dir;
 
                Hashtable values;
                string file;
                bool dirty;
-               
+
                KeyHandler (RegistryKey rkey, string basedir)
                {
                        if (!Directory.Exists (basedir)){
-                               Directory.CreateDirectory (basedir);
+                               try {
+                                       Directory.CreateDirectory (basedir);
+                               } catch (UnauthorizedAccessException){
+                                       throw new SecurityException ("No access to the given key");
+                               }
                        }
                        Dir = basedir;
                        file = Path.Combine (Dir, "values.xml");
@@ -136,6 +138,9 @@ namespace Microsoft.Win32 {
                                                }
                                        }
                                }
+                       } catch (UnauthorizedAccessException){
+                               values.Clear ();
+                               throw new SecurityException ("No access to the given key");
                        } catch (Exception e){
                                Console.Error.WriteLine ("While loading registry key at {0}: {1}", file, e);
                                values.Clear ();
@@ -158,7 +163,7 @@ namespace Microsoft.Win32 {
                                        values [name] = Int32.Parse (se.Text);
                                        break;
                                case "bytearray":
-                                       Convert.FromBase64String (se.Text);
+                                       values [name] = Convert.FromBase64String (se.Text);
                                        break;
                                case "string":
                                        values [name] = se.Text;
@@ -253,9 +258,9 @@ namespace Microsoft.Win32 {
                                case RegistryHive.LocalMachine:
                                case RegistryHive.PerformanceData:
                                case RegistryHive.Users:
-                                       string machineDir = Path.Combine (MachineStore, x.ToString ());
-                                       k = new KeyHandler (rkey, machineDir);
-                                       dir_to_handler [machineDir] = k;
+                                       string machine_dir = Path.Combine (MachineStore, x.ToString ());
+                                       k = new KeyHandler (rkey, machine_dir);
+                                       dir_to_handler [machine_dir] = k;
                                        break;
                                default:
                                        throw new Exception ("Unknown RegistryHive");
@@ -354,6 +359,10 @@ namespace Microsoft.Win32 {
                public void SetValue (string name, object value, RegistryValueKind valueKind)
                {
                        SetDirty ();
+
+                       if (name == null)
+                               name = string.Empty;
+
                        switch (valueKind){
                        case RegistryValueKind.String:
                                if (value is string){
@@ -480,14 +489,16 @@ namespace Microsoft.Win32 {
 
                        SecurityElement se = new SecurityElement ("values");
                        
+                       // With SecurityElement.Text = value, and SecurityElement.AddAttribute(key, value)
+                       // the values must be escaped prior to being assigned. 
                        foreach (DictionaryEntry de in values){
                                object val = de.Value;
                                SecurityElement value = new SecurityElement ("value");
-                               value.AddAttribute ("name", (string) de.Key);
+                               value.AddAttribute ("name", SecurityElement.Escape ((string) de.Key));
                                
                                if (val is string){
                                        value.AddAttribute ("type", "string");
-                                       value.Text = (string) val;
+                                       value.Text = SecurityElement.Escape ((string) val);
                                } else if (val is int){
                                        value.AddAttribute ("type", "int");
                                        value.Text = val.ToString ();
@@ -499,13 +510,13 @@ namespace Microsoft.Win32 {
                                        value.Text = Convert.ToBase64String ((byte[]) val);
                                } else if (val is ExpandString){
                                        value.AddAttribute ("type", "expand");
-                                       value.Text = val.ToString ();
+                                       value.Text = SecurityElement.Escape (val.ToString ());
                                } else if (val is string []){
                                        value.AddAttribute ("type", "string-array");
 
                                        foreach (string ss in (string[]) val){
                                                SecurityElement str = new SecurityElement ("string");
-                                               str.Text = ss
+                                               str.Text = SecurityElement.Escape (ss)
                                                value.AddChild (str);
                                        }
                                }
@@ -535,13 +546,14 @@ namespace Microsoft.Win32 {
 
                private static string MachineStore {
                        get {
-                               /*
-                               string machineStore = Environment.GetEnvironmentVariable (MACHINE_STORE_VAR);
-                               if (machineStore != null)
-                                       return machineStore;
-                               */
-                               return UserStore;
-                               // return "/var/lib/mono/registry";
+                               string s;
+
+                               s = Environment.GetEnvironmentVariable ("MONO_REGISTRY_PATH");
+                               if (s != null)
+                                       return s;
+                               s = Environment.GetMachineConfigPath ();
+                               int p = s.IndexOf ("machine.config");
+                               return Path.Combine (Path.Combine (s.Substring (0, p-1), ".."), "registry");
                        }
                }
        }
@@ -586,7 +598,7 @@ namespace Microsoft.Win32 {
                        RegistryKey result = self.Probe (rkey, ToUnix (keyname), writable);
                        if (result == null && IsWellKnownKey (rkey.Name, keyname)) {
                                // create the subkey even if its parent was opened read-only
-                               result = CreateSubKey (rkey, keyname, false);
+                               result = CreateSubKey (rkey, keyname, writable);
                        }
 
                        return result;
@@ -664,7 +676,7 @@ namespace Microsoft.Win32 {
                        }
 
                        if (throw_if_missing && !self.ValueExists (name))
-                               throw new ArgumentException ("the given value does not exist", "name");
+                               throw new ArgumentException ("the given value does not exist");
 
                        self.RemoveValue (name);
                }
@@ -676,7 +688,7 @@ namespace Microsoft.Win32 {
                                // key is marked for deletion
                                if (!throw_if_missing)
                                        return;
-                               throw new ArgumentException ("the given value does not exist", "value");
+                               throw new ArgumentException ("the given value does not exist");
                        }
 
                        string dir = Path.Combine (self.Dir, ToUnix (keyname));
@@ -685,7 +697,7 @@ namespace Microsoft.Win32 {
                                Directory.Delete (dir, true);
                                KeyHandler.Drop (dir);
                        } else if (throw_if_missing)
-                               throw new ArgumentException ("the given value does not exist", "value");
+                               throw new ArgumentException ("the given value does not exist");
                }
                
                public string [] GetSubKeyNames (RegistryKey rkey)
@@ -723,3 +735,6 @@ namespace Microsoft.Win32 {
                }
        }
 }
+
+#endif // NET_2_1
+