X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FMicrosoft.Win32%2FWin32RegistryApi.cs;h=472f4a73c5b9a4d076e0f205851f92d90d4b372c;hb=44dbdaa1f96e43b5b106dc9fab01d8dd6b51f774;hp=1849a46f4e1e4a2c6d5fc81d6a5e6488e203f346;hpb=c39d7ce9985a7067c1cbf44188007c9433901940;p=mono.git diff --git a/mcs/class/corlib/Microsoft.Win32/Win32RegistryApi.cs b/mcs/class/corlib/Microsoft.Win32/Win32RegistryApi.cs index 1849a46f4e1..472f4a73c5b 100644 --- a/mcs/class/corlib/Microsoft.Win32/Win32RegistryApi.cs +++ b/mcs/class/corlib/Microsoft.Win32/Win32RegistryApi.cs @@ -33,12 +33,15 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !NET_2_1 + using System; using System.Collections; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Text; +using Microsoft.Win32.SafeHandles; namespace Microsoft.Win32 { @@ -58,8 +61,13 @@ namespace Microsoft.Win32 // FIXME this is hard coded on Mono, can it be determined dynamically? readonly int NativeBytesPerCharacter = Marshal.SystemDefaultCharSize; - [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegCreateKey")] - static extern int RegCreateKey (IntPtr keyBase, string keyName, out IntPtr keyHandle); + const int RegOptionsNonVolatile = 0x00000000; + const int RegOptionsVolatile = 0x00000001; + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegCreateKeyEx")] + static extern int RegCreateKeyEx (IntPtr keyBase, string keyName, int reserved, + IntPtr lpClass, int options, int access, IntPtr securityAttrs, + out IntPtr keyHandle, out int disposition); [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegCloseKey")] static extern int RegCloseKey (IntPtr keyHandle); @@ -91,10 +99,10 @@ namespace Microsoft.Win32 ref int nameLength, IntPtr reserved, ref RegistryValueKind type, IntPtr data, IntPtr dataLength); - [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegSetValueEx")] - private static extern int RegSetValueEx (IntPtr keyBase, - string valueName, IntPtr reserved, RegistryValueKind type, - StringBuilder data, int rawDataLength); +// [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegSetValueEx")] +// private static extern int RegSetValueEx (IntPtr keyBase, +// string valueName, IntPtr reserved, RegistryValueKind type, +// StringBuilder data, int rawDataLength); [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="RegSetValueEx")] private static extern int RegSetValueEx (IntPtr keyBase, @@ -127,16 +135,29 @@ namespace Microsoft.Win32 ref int data, ref int dataSize); // Returns our handle from the RegistryKey - static IntPtr GetHandle (RegistryKey key) + public IntPtr GetHandle (RegistryKey key) { - return (IntPtr) key.Handle; + return (IntPtr) key.InternalHandle; } static bool IsHandleValid (RegistryKey key) { - return key.Handle != null; + return key.InternalHandle != null; } + public RegistryValueKind GetValueKind (RegistryKey rkey, string name) + { + RegistryValueKind type = 0; + int size = 0; + IntPtr handle = GetHandle (rkey); + int result = RegQueryValueEx (handle, name, IntPtr.Zero, ref type, IntPtr.Zero, ref size); + + if (result == Win32ResultCode.FileNotFound || result == Win32ResultCode.MarkedForDeletion) + return RegistryValueKind.Unknown; + + return type; + } + /// /// Acctually read a registry value. Requires knowledge of the /// value's type and size. @@ -197,7 +218,6 @@ namespace Microsoft.Win32 return obj; } -#if NET_2_0 // // This version has to do extra checking, make sure that the requested // valueKind matches the type of the value being stored @@ -245,7 +265,6 @@ namespace Microsoft.Win32 GenerateException (result); } } -#endif public void SetValue (RegistryKey rkey, string name, object value) { @@ -409,11 +428,24 @@ namespace Microsoft.Win32 RegCloseKey (handle); } +#if NET_4_0 + public RegistryKey FromHandle (SafeRegistryHandle handle) + { + // At this point we can't tell whether the key is writable + // or not (nor the name), so we let the error check code handle it later, as + // .Net seems to do. + return new RegistryKey (handle.DangerousGetHandle (), String.Empty, true); + } +#endif + public RegistryKey CreateSubKey (RegistryKey rkey, string keyName) { IntPtr handle = GetHandle (rkey); IntPtr subKeyHandle; - int result = RegCreateKey (handle , keyName, out subKeyHandle); + int disposition; + int result = RegCreateKeyEx (handle , keyName, 0, IntPtr.Zero, + RegOptionsNonVolatile, + OpenRegKeyRead | OpenRegKeyWrite, IntPtr.Zero, out subKeyHandle, out disposition); if (result == Win32ResultCode.MarkedForDeletion) throw RegistryKey.CreateMarkedForDeletionException (); @@ -426,6 +458,27 @@ namespace Microsoft.Win32 true); } +#if NET_4_0 + public RegistryKey CreateSubKey (RegistryKey rkey, string keyName, RegistryOptions options) + { + IntPtr handle = GetHandle (rkey); + IntPtr subKeyHandle; + int disposition; + int result = RegCreateKeyEx (handle , keyName, 0, IntPtr.Zero, + options == RegistryOptions.Volatile ? RegOptionsVolatile : RegOptionsNonVolatile, + OpenRegKeyRead | OpenRegKeyWrite, IntPtr.Zero, out subKeyHandle, out disposition); + + if (result == Win32ResultCode.MarkedForDeletion) + throw RegistryKey.CreateMarkedForDeletionException (); + + if (result != Win32ResultCode.Success) + GenerateException (result); + + return new RegistryKey (subKeyHandle, CombineName (rkey, keyName), + true); + } +#endif + public void DeleteKey (RegistryKey rkey, string keyName, bool shouldThrowWhenKeyMissing) { IntPtr handle = GetHandle (rkey); @@ -528,6 +581,8 @@ namespace Microsoft.Win32 throw new SecurityException (); case Win32ResultCode.NetworkPathNotFound: throw new IOException ("The network path was not found."); + case Win32ResultCode.InvalidHandle: + throw new IOException ("Invalid handle."); default: // unidentified system exception throw new SystemException (); @@ -536,9 +591,7 @@ namespace Microsoft.Win32 public string ToString (RegistryKey rkey) { - IntPtr handle = GetHandle (rkey); - - return String.Format ("{0} [0x{1:X}]", rkey.Name, handle.ToInt32 ()); + return rkey.Name; } /// @@ -552,3 +605,5 @@ namespace Microsoft.Win32 } } +#endif // NET_2_1 +