From 26bf150dda279dd068c76c6502bdd269ec3fb976 Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Fri, 7 Apr 2017 14:21:47 -0700 Subject: [PATCH] Strip out unused reg code. (dotnet/coreclr#10741) * Strip out unused reg code. Removing the unused code to better be able to audit our CoreLib usage and to prepare for targeted code sharing with CoreFX. Wraps key usages in using statements. * Fix static init and remove Contract Commit migrated from https://github.com/dotnet/coreclr/commit/ed4f594abf41a71b126152bb8755051d0831e12d --- .../src/mscorlib/System.Private.CoreLib.csproj | 5 +- .../System/Diagnostics/Tracing/EventProvider.cs | 18 +- .../src/mscorlib/src/Microsoft/Win32/Registry.cs | 134 +--- .../mscorlib/src/Microsoft/Win32/RegistryKey.cs | 672 ++------------------- .../src/Microsoft/Win32/RegistryValueKind.cs | 10 +- .../mscorlib/src/Microsoft/Win32/RegistryView.cs | 22 - .../Win32/SafeHandles/SafeRegistryHandle.cs | 10 - src/coreclr/src/mscorlib/src/System/Environment.cs | 2 +- .../System/Globalization/HijriCalendar.Win32.cs | 61 +- .../System/Globalization/JapaneseCalendar.Win32.cs | 38 +- .../src/mscorlib/src/System/TimeZoneInfo.Win32.cs | 28 +- 11 files changed, 139 insertions(+), 861 deletions(-) delete mode 100644 src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryView.cs diff --git a/src/coreclr/src/mscorlib/System.Private.CoreLib.csproj b/src/coreclr/src/mscorlib/System.Private.CoreLib.csproj index 2ded505..ff62e7d 100644 --- a/src/coreclr/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/coreclr/src/mscorlib/System.Private.CoreLib.csproj @@ -86,11 +86,9 @@ portable - PLATFORM_OSX;$(DefineConstants) - System.Private.CoreLib @@ -753,7 +751,6 @@ - @@ -873,4 +870,4 @@ $(IntermediateOutputPath)\System.Private.CoreLib.res - + \ No newline at end of file diff --git a/src/coreclr/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/coreclr/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs index e18574c..57d550d 100644 --- a/src/coreclr/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/coreclr/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs @@ -555,21 +555,21 @@ namespace System.Diagnostics.Tracing { #if (!ES_BUILD_PCL && !ES_BUILD_PN && !FEATURE_PAL) string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}"; - if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8) - regKey = @"HKEY_LOCAL_MACHINE\Software" + @"\Wow6432Node" + regKey; + if (Marshal.SizeOf(typeof(IntPtr)) == 8) + regKey = @"Software" + @"\Wow6432Node" + regKey; else - regKey = @"HKEY_LOCAL_MACHINE\Software" + regKey; + regKey = @"Software" + regKey; string valueName = "ControllerData_Session_" + etwSessionId.ToString(CultureInfo.InvariantCulture); - // we need to assert this permission for partial trust scenarios -#if !CORECLR - (new RegistryPermission(RegistryPermissionAccess.Read, regKey)).Assert(); -#endif - data = Microsoft.Win32.Registry.GetValue(regKey, valueName, null) as byte[]; + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey, writable: false)) + { + data = key.GetValue(valueName) as byte[]; + } + if (data != null) { - // We only used the persisted data from the registry for updates. + // We only used the persisted data from the registry for updates. command = ControllerCommand.Update; return true; } diff --git a/src/coreclr/src/mscorlib/src/Microsoft/Win32/Registry.cs b/src/coreclr/src/mscorlib/src/Microsoft/Win32/Registry.cs index d0dbb0f..aa2dd9b 100644 --- a/src/coreclr/src/mscorlib/src/Microsoft/Win32/Registry.cs +++ b/src/coreclr/src/mscorlib/src/Microsoft/Win32/Registry.cs @@ -2,142 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; - namespace Microsoft.Win32 { - /** - * Registry encapsulation. Contains members representing all top level system - * keys. - * - * @security(checkClassLinking=on) - */ - //This class contains only static members and does not need to be serializable. internal static class Registry { - /** - * Current User Key. - * - * This key should be used as the root for all user specific settings. - */ - public static readonly RegistryKey CurrentUser = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER); - - /** - * Local Machine Key. - * - * This key should be used as the root for all machine specific settings. - */ - public static readonly RegistryKey LocalMachine = RegistryKey.GetBaseKey(RegistryKey.HKEY_LOCAL_MACHINE); - - /** - * Classes Root Key. - * - * This is the root key of class information. - */ - public static readonly RegistryKey ClassesRoot = RegistryKey.GetBaseKey(RegistryKey.HKEY_CLASSES_ROOT); - - /** - * Users Root Key. - * - * This is the root of users. - */ - public static readonly RegistryKey Users = RegistryKey.GetBaseKey(RegistryKey.HKEY_USERS); - - /** - * Performance Root Key. - * - * This is where dynamic performance data is stored on NT. - */ - public static readonly RegistryKey PerformanceData = RegistryKey.GetBaseKey(RegistryKey.HKEY_PERFORMANCE_DATA); - - /** - * Current Config Root Key. - * - * This is where current configuration information is stored. - */ - public static readonly RegistryKey CurrentConfig = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_CONFIG); - - // - // Following function will parse a keyName and returns the basekey for it. - // It will also store the subkey name in the out parameter. - // If the keyName is not valid, we will throw ArgumentException. - // The return value shouldn't be null. - // - private static RegistryKey GetBaseKeyFromKeyName(string keyName, out string subKeyName) - { - if (keyName == null) - { - throw new ArgumentNullException(nameof(keyName)); - } - - string basekeyName; - int i = keyName.IndexOf('\\'); - if (i != -1) - { - basekeyName = keyName.Substring(0, i).ToUpper(System.Globalization.CultureInfo.InvariantCulture); - } - else - { - basekeyName = keyName.ToUpper(System.Globalization.CultureInfo.InvariantCulture); - } - RegistryKey basekey = null; - - switch (basekeyName) - { - case "HKEY_CURRENT_USER": - basekey = Registry.CurrentUser; - break; - case "HKEY_LOCAL_MACHINE": - basekey = Registry.LocalMachine; - break; - case "HKEY_CLASSES_ROOT": - basekey = Registry.ClassesRoot; - break; - case "HKEY_USERS": - basekey = Registry.Users; - break; - case "HKEY_PERFORMANCE_DATA": - basekey = Registry.PerformanceData; - break; - case "HKEY_CURRENT_CONFIG": - basekey = Registry.CurrentConfig; - break; - default: - throw new ArgumentException(SR.Format(SR.Arg_RegInvalidKeyName, nameof(keyName))); - } - if (i == -1 || i == keyName.Length) - { - subKeyName = string.Empty; - } - else - { - subKeyName = keyName.Substring(i + 1, keyName.Length - i - 1); - } - return basekey; - } - - public static object GetValue(string keyName, string valueName, object defaultValue) - { - string subKeyName; - RegistryKey basekey = GetBaseKeyFromKeyName(keyName, out subKeyName); - BCLDebug.Assert(basekey != null, "basekey can't be null."); - RegistryKey key = basekey.OpenSubKey(subKeyName); - if (key == null) - { // if the key doesn't exist, do nothing - return null; - } - try - { - return key.GetValue(valueName, defaultValue); - } - finally - { - key.Close(); - } - } + public static readonly RegistryKey CurrentUser = RegistryKey.CurrentUser; + public static readonly RegistryKey LocalMachine = RegistryKey.LocalMachine; } } diff --git a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs index 521ea65..e39b959 100644 --- a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs +++ b/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs @@ -2,28 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - -/* - Note on transaction support: - Eventually we will want to add support for NT's transactions to our - RegistryKey API's (possibly Whidbey M3?). When we do this, here's - the list of API's we need to make transaction-aware: - - RegCreateKeyEx - RegDeleteKey - RegDeleteValue - RegEnumKeyEx - RegEnumValue - RegOpenKeyEx - RegQueryInfoKey - RegQueryValueEx - RegSetValueEx - - We can ignore RegConnectRegistry (remote registry access doesn't yet have - transaction support) and RegFlushKey. RegCloseKey doesn't require any - additional work. . - */ - /* Note on ACL support: The key thing to note about ACL's is you set them on a kernel object like a @@ -52,34 +30,28 @@ using Microsoft.Win32.SafeHandles; using System; using System.Buffers; using System.Collections.Generic; -using System.Diagnostics.Contracts; +using System.Diagnostics; using System.IO; -using System.Text; namespace Microsoft.Win32 { /** * Registry encapsulation. To get an instance of a RegistryKey use the * Registry class's static members then call OpenSubKey. - * - * @see Registry - * @security(checkDllCalls=off) - * @security(checkClassLinking=on) */ internal sealed class RegistryKey : MarshalByRefObject, IDisposable { + // Use the public Registry.CurrentUser + internal static readonly RegistryKey CurrentUser = + GetBaseKey(new IntPtr(unchecked((int)0x80000001)), "HKEY_CURRENT_USER"); + + // Use the public Registry.LocalMachine + internal static readonly RegistryKey LocalMachine = + GetBaseKey(new IntPtr(unchecked((int)0x80000002)), "HKEY_LOCAL_MACHINE"); + // We could use const here, if C# supported ELEMENT_TYPE_I fully. - internal static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000)); - internal static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001)); - internal static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002)); - internal static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003)); - internal static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004)); - internal static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005)); - - // Dirty indicates that we have munged data that should be potentially - // written to disk. - // - private const int STATE_DIRTY = 0x0001; + private static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001)); + private static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002)); // SystemKey indicates that this is a "SYSTEMKEY" and shouldn't be "opened" // or "closed". @@ -90,20 +62,6 @@ namespace Microsoft.Win32 // private const int STATE_WRITEACCESS = 0x0004; - // Indicates if this key is for HKEY_PERFORMANCE_DATA - private const int STATE_PERF_DATA = 0x0008; - - // Names of keys. This array must be in the same order as the HKEY values listed above. - // - private static readonly String[] hkeyNames = new String[] { - "HKEY_CLASSES_ROOT", - "HKEY_CURRENT_USER", - "HKEY_LOCAL_MACHINE", - "HKEY_USERS", - "HKEY_PERFORMANCE_DATA", - "HKEY_CURRENT_CONFIG", - }; - // MSDN defines the following limits for registry key names & values: // Key Name: 255 characters // Value name: 16,383 Unicode characters @@ -113,31 +71,7 @@ namespace Microsoft.Win32 private volatile SafeRegistryHandle hkey = null; private volatile int state = 0; - private volatile String keyName; - private volatile bool remoteKey = false; - private volatile RegistryKeyPermissionCheck checkMode; - private volatile RegistryView regView = RegistryView.Default; - - /** - * RegistryInternalCheck values. Useful only for CheckPermission - */ - private enum RegistryInternalCheck - { - CheckSubKeyWritePermission = 0, - CheckSubKeyReadPermission = 1, - CheckSubKeyCreatePermission = 2, - CheckSubTreeReadPermission = 3, - CheckSubTreeWritePermission = 4, - CheckSubTreeReadWritePermission = 5, - CheckValueWritePermission = 6, - CheckValueCreatePermission = 7, - CheckValueReadPermission = 8, - CheckKeyReadPermission = 9, - CheckSubTreePermission = 10, - CheckOpenSubKeyWithWritablePermission = 11, - CheckOpenSubKeyPermission = 12 - }; - + private volatile string keyName; /** * Creates a RegistryKey. @@ -148,12 +82,10 @@ namespace Microsoft.Win32 * The remoteKey flag when set to true indicates that we are dealing with registry entries * on a remote machine and requires the program making these calls to have full trust. */ - private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey, bool remoteKey, bool isPerfData, RegistryView view) + private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey) { this.hkey = hkey; keyName = ""; - this.remoteKey = remoteKey; - regView = view; if (systemkey) { state |= STATE_SYSTEMKEY; @@ -162,17 +94,6 @@ namespace Microsoft.Win32 { state |= STATE_WRITEACCESS; } - if (isPerfData) - state |= STATE_PERF_DATA; - ValidateKeyView(view); - } - - /** - * Closes this key, flushes it to disk if the contents have been modified. - */ - public void Close() - { - Dispose(true); } private void Dispose(bool disposing) @@ -194,21 +115,6 @@ namespace Microsoft.Win32 hkey = null; } } - else if (disposing && IsPerfDataKey()) - { - // System keys should never be closed. However, we want to call RegCloseKey - // on HKEY_PERFORMANCE_DATA when called from PerformanceCounter.CloseSharedResources - // (i.e. when disposing is true) so that we release the PERFLIB cache and cause it - // to be refreshed (by re-reading the registry) when accessed subsequently. - // This is the only way we can see the just installed perf counter. - // NOTE: since HKEY_PERFORMANCE_DATA is process wide, there is inherent race condition in closing - // the key asynchronously. While Vista is smart enough to rebuild the PERFLIB resources - // in this situation the down level OSes are not. We have a small window between - // the dispose below and usage elsewhere (other threads). This is By Design. - // This is less of an issue when OS > NT5 (i.e Vista & higher), we can close the perfkey - // (to release & refresh PERFLIB resources) and the OS will rebuild PERFLIB as necessary. - SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA); - } } } @@ -217,13 +123,13 @@ namespace Microsoft.Win32 Dispose(true); } - public void DeleteValue(String name, bool throwOnMissingValue) + public void DeleteValue(string name, bool throwOnMissingValue) { EnsureWriteable(); int errorCode = Win32Native.RegDeleteValue(hkey, name); // - // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE + // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE // This still means the name doesn't exist. We need to be consistent with previous OS. // if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) @@ -232,77 +138,44 @@ namespace Microsoft.Win32 { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent); } + // Otherwise, just return giving no indication to the user. // (For compatibility) } + // We really should throw an exception here if errorCode was bad, // but we can't for compatibility reasons. - BCLDebug.Correctness(errorCode == 0, "RegDeleteValue failed. Here's your error code: " + errorCode); - } - - /** - * Retrieves a new RegistryKey that represents the requested key. Valid - * values are: - * - * HKEY_CLASSES_ROOT, - * HKEY_CURRENT_USER, - * HKEY_LOCAL_MACHINE, - * HKEY_USERS, - * HKEY_PERFORMANCE_DATA, - * HKEY_CURRENT_CONFIG, - * HKEY_DYN_DATA. - * - * @param hKey HKEY_* to open. - * - * @return the RegistryKey requested. - */ - internal static RegistryKey GetBaseKey(IntPtr hKey) - { - return GetBaseKey(hKey, RegistryView.Default); + Debug.Assert(errorCode == 0, "RegDeleteValue failed. Here's your error code: " + errorCode); } - internal static RegistryKey GetBaseKey(IntPtr hKey, RegistryView view) + private static RegistryKey GetBaseKey(IntPtr hKey, string keyName) { - int index = ((int)hKey) & 0x0FFFFFFF; - BCLDebug.Assert(index >= 0 && index < hkeyNames.Length, "index is out of range!"); - BCLDebug.Assert((((int)hKey) & 0xFFFFFFF0) == 0x80000000, "Invalid hkey value!"); - - bool isPerf = hKey == HKEY_PERFORMANCE_DATA; - // only mark the SafeHandle as ownsHandle if the key is HKEY_PERFORMANCE_DATA. - SafeRegistryHandle srh = new SafeRegistryHandle(hKey, isPerf); + SafeRegistryHandle srh = new SafeRegistryHandle(hKey, ownsHandle: false); - RegistryKey key = new RegistryKey(srh, true, true, false, isPerf, view); - key.checkMode = RegistryKeyPermissionCheck.Default; - key.keyName = hkeyNames[index]; + RegistryKey key = new RegistryKey(srh, true, true); + key.keyName = keyName; return key; } - /** - * Retrieves a subkey. If readonly is true, then the subkey is opened with - * read-only access. - * - * @param name Name or path of subkey to open. - * @param readonly Set to true if you only need readonly access. - * - * @return the Subkey requested, or null if the operation failed. - */ + /// + /// Retrieves a subkey or null if the operation failed. + /// + /// True to open writable, otherwise opens the key read-only. public RegistryKey OpenSubKey(string name, bool writable) { ValidateKeyName(name); EnsureNotDisposed(); - name = FixupName(name); // Fixup multiple slashes to a single slash SafeRegistryHandle result = null; int ret = Win32Native.RegOpenKeyEx(hkey, name, 0, - GetRegistryKeyAccess(writable) | (int)regView, + writable ? Win32Native.KEY_READ | Win32Native.KEY_WRITE : Win32Native.KEY_READ, out result); if (ret == 0 && !result.IsInvalid) { - RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView); - key.checkMode = GetSubKeyPermissonCheck(writable); + RegistryKey key = new RegistryKey(result, writable, false); key.keyName = keyName + "\\" + name; return key; } @@ -318,41 +191,6 @@ namespace Microsoft.Win32 return null; } - // This required no security checks. This is to get around the Deleting SubKeys which only require - // write permission. They call OpenSubKey which required read. Now instead call this function w/o security checks - internal RegistryKey InternalOpenSubKey(String name, bool writable) - { - ValidateKeyName(name); - EnsureNotDisposed(); - - SafeRegistryHandle result = null; - int ret = Win32Native.RegOpenKeyEx(hkey, - name, - 0, - GetRegistryKeyAccess(writable) | (int)regView, - out result); - - if (ret == 0 && !result.IsInvalid) - { - RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView); - key.keyName = keyName + "\\" + name; - return key; - } - return null; - } - - /** - * Returns a subkey with read only permissions. - * - * @param name Name or path of subkey to open. - * - * @return the Subkey requested, or null if the operation failed. - */ - public RegistryKey OpenSubKey(String name) - { - return OpenSubKey(name, false); - } - /// /// Retrieves an array of strings containing all the subkey names. /// @@ -481,22 +319,6 @@ namespace Microsoft.Win32 } /** - * Retrieves the specified value. null is returned if the value - * doesn't exist. - * - * Note that name can be null or "", at which point the - * unnamed or default value of this Registry key is returned, if any. - * - * @param name Name of value to retrieve. - * - * @return the data associated with the value. - */ - public Object GetValue(String name) - { - return InternalGetValue(name, null, false, true); - } - - /** * Retrieves the specified value. defaultValue is returned if the value doesn't exist. * * Note that name can be null or "", at which point the @@ -511,30 +333,11 @@ namespace Microsoft.Win32 * * @return the data associated with the value. */ - public Object GetValue(String name, Object defaultValue) - { - return InternalGetValue(name, defaultValue, false, true); - } - - public Object GetValue(String name, Object defaultValue, RegistryValueOptions options) - { - if (options < RegistryValueOptions.None || options > RegistryValueOptions.DoNotExpandEnvironmentNames) - { - throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options)); - } - bool doNotExpand = (options == RegistryValueOptions.DoNotExpandEnvironmentNames); - return InternalGetValue(name, defaultValue, doNotExpand, true); - } - - internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity) + public object GetValue(string name, object defaultValue = null, bool doNotExpand = false) { - if (checkSecurity) - { - // Name can be null! It's the most common use of RegQueryValueEx - EnsureNotDisposed(); - } + EnsureNotDisposed(); - Object data = defaultValue; + object data = defaultValue; int type = 0; int datasize = 0; @@ -542,54 +345,20 @@ namespace Microsoft.Win32 if (ret != 0) { - if (IsPerfDataKey()) - { - int size = 65000; - int sizeInput = size; - - int r; - byte[] blob = new byte[size]; - while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) - { - if (size == Int32.MaxValue) - { - // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond Int32.MaxValue - Win32Error(r, name); - } - else if (size > (Int32.MaxValue / 2)) - { - // at this point in the loop "size * 2" would cause an overflow - size = Int32.MaxValue; - } - else - { - size *= 2; - } - sizeInput = size; - blob = new byte[size]; - } - if (r != 0) - Win32Error(r, name); - return blob; - } - else - { - // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data). - // Some OS's returned ERROR_MORE_DATA even in success cases, so we - // want to continue on through the function. - if (ret != Win32Native.ERROR_MORE_DATA) - return data; - } + // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data). + // Some OS's returned ERROR_MORE_DATA even in success cases, so we + // want to continue on through the function. + if (ret != Win32Native.ERROR_MORE_DATA) + return data; } if (datasize < 0) { // unexpected code path - BCLDebug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize"); + Debug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize"); datasize = 0; } - switch (type) { case Win32Native.REG_NONE: @@ -609,7 +378,7 @@ namespace Microsoft.Win32 goto case Win32Native.REG_BINARY; } long blob = 0; - BCLDebug.Assert(datasize == 8, "datasize==8"); + Debug.Assert(datasize == 8, "datasize==8"); // Here, datasize must be 8 when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); @@ -624,7 +393,7 @@ namespace Microsoft.Win32 goto case Win32Native.REG_QWORD; } int blob = 0; - BCLDebug.Assert(datasize == 4, "datasize==4"); + Debug.Assert(datasize == 4, "datasize==4"); // Here, datasize must be four when calling this ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize); @@ -651,13 +420,13 @@ namespace Microsoft.Win32 ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { - data = new String(blob, 0, blob.Length - 1); + data = new string(blob, 0, blob.Length - 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character - data = new String(blob); + data = new string(blob); } } break; @@ -682,17 +451,17 @@ namespace Microsoft.Win32 if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { - data = new String(blob, 0, blob.Length - 1); + data = new string(blob, 0, blob.Length - 1); } else { // in the very unlikely case the data is missing null termination, // pass in the whole char[] to prevent truncating a character - data = new String(blob); + data = new string(blob); } if (!doNotExpand) - data = Environment.ExpandEnvironmentVariables((String)data); + data = Environment.ExpandEnvironmentVariables((string)data); } break; case Win32Native.REG_MULTI_SZ: @@ -733,8 +502,7 @@ namespace Microsoft.Win32 blob[blob.Length - 1] = (char)0; } - - IList strings = new List(); + IList strings = new List(); int cur = 0; int len = blob.Length; @@ -748,28 +516,28 @@ namespace Microsoft.Win32 if (nextNull < len) { - BCLDebug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0"); + Debug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0"); if (nextNull - cur > 0) { - strings.Add(new String(blob, cur, nextNull - cur)); + strings.Add(new string(blob, cur, nextNull - cur)); } else { // we found an empty string. But if we're at the end of the data, // it's just the extra null terminator. if (nextNull != len - 1) - strings.Add(String.Empty); + strings.Add(string.Empty); } } else { - strings.Add(new String(blob, cur, len - cur)); + strings.Add(new string(blob, cur, len - cur)); } cur = nextNull + 1; } - data = new String[strings.Count]; - strings.CopyTo((String[])data, 0); + data = new string[strings.Count]; + strings.CopyTo((string[])data, 0); } break; case Win32Native.REG_LINK: @@ -792,26 +560,10 @@ namespace Microsoft.Win32 private bool IsPerfDataKey() { - return (state & STATE_PERF_DATA) != 0; - } - - private void SetDirty() - { - state |= STATE_DIRTY; - } - - /** - * Sets the specified value. - * - * @param name Name of value to store data in. - * @param value Data to store. - */ - public void SetValue(String name, Object value) - { - SetValue(name, value, RegistryValueKind.Unknown); + return false; } - public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind) + public unsafe void SetStringValue(string name, string value) { if (value == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); @@ -821,167 +573,17 @@ namespace Microsoft.Win32 throw new ArgumentException(SR.Arg_RegValStrLenBug); } - if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind)) - throw new ArgumentException(SR.Arg_RegBadKeyKind, nameof(valueKind)); - EnsureWriteable(); - if (valueKind == RegistryValueKind.Unknown) - { - // this is to maintain compatibility with the old way of autodetecting the type. - // SetValue(string, object) will come through this codepath. - valueKind = CalculateValueKind(value); - } - - int ret = 0; - try - { - switch (valueKind) - { - case RegistryValueKind.ExpandString: - case RegistryValueKind.String: - { - String data = value.ToString(); - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - valueKind, - data, - checked(data.Length * 2 + 2)); - break; - } - - case RegistryValueKind.MultiString: - { - // Other thread might modify the input array after we calculate the buffer length. - // Make a copy of the input array to be safe. - string[] dataStrings = (string[])(((string[])value).Clone()); - int sizeInBytes = 0; - - // First determine the size of the array - // - for (int i = 0; i < dataStrings.Length; i++) - { - if (dataStrings[i] == null) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetStrArrNull); - } - sizeInBytes = checked(sizeInBytes + (dataStrings[i].Length + 1) * 2); - } - sizeInBytes = checked(sizeInBytes + 2); - - byte[] basePtr = new byte[sizeInBytes]; - fixed (byte* b = basePtr) - { - IntPtr currentPtr = new IntPtr((void*)b); - - // Write out the strings... - // - for (int i = 0; i < dataStrings.Length; i++) - { - // Assumes that the Strings are always null terminated. - String.InternalCopy(dataStrings[i], currentPtr, (checked(dataStrings[i].Length * 2))); - currentPtr = new IntPtr((long)currentPtr + (checked(dataStrings[i].Length * 2))); - *(char*)(currentPtr.ToPointer()) = '\0'; - currentPtr = new IntPtr((long)currentPtr + 2); - } - - *(char*)(currentPtr.ToPointer()) = '\0'; - currentPtr = new IntPtr((long)currentPtr + 2); - - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - RegistryValueKind.MultiString, - basePtr, - sizeInBytes); - } - break; - } - - case RegistryValueKind.None: - case RegistryValueKind.Binary: - byte[] dataBytes = (byte[])value; - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - (valueKind == RegistryValueKind.None ? Win32Native.REG_NONE : RegistryValueKind.Binary), - dataBytes, - dataBytes.Length); - break; - - case RegistryValueKind.DWord: - { - // We need to use Convert here because we could have a boxed type cannot be - // unboxed and cast at the same time. I.e. ((int)(object)(short) 5) will fail. - int data = Convert.ToInt32(value, System.Globalization.CultureInfo.InvariantCulture); - - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - RegistryValueKind.DWord, - ref data, - 4); - break; - } - - case RegistryValueKind.QWord: - { - long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture); - - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - RegistryValueKind.QWord, - ref data, - 8); - break; - } - } - } - catch (OverflowException) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); - } - catch (InvalidOperationException) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); - } - catch (FormatException) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); - } - catch (InvalidCastException) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind); - } - - if (ret == 0) - { - SetDirty(); - } - else - Win32Error(ret, null); - } + int result = Win32Native.RegSetValueEx(hkey, + name, + 0, + RegistryValueKind.String, + value, + checked(value.Length * 2 + 2)); - private RegistryValueKind CalculateValueKind(Object value) - { - // This logic matches what used to be in SetValue(string name, object value) in the v1.0 and v1.1 days. - // Even though we could add detection for an int64 in here, we want to maintain compatibility with the - // old behavior. - if (value is Int32) - return RegistryValueKind.DWord; - else if (value is Array) - { - if (value is byte[]) - return RegistryValueKind.Binary; - else if (value is String[]) - return RegistryValueKind.MultiString; - else - throw new ArgumentException(SR.Format(SR.Arg_RegSetBadArrType, value.GetType().Name)); - } - else - return RegistryValueKind.String; + if (result != 0) + Win32Error(result, null); } /** @@ -989,7 +591,7 @@ namespace Microsoft.Win32 * * @return a string representing the key. */ - public override String ToString() + public override string ToString() { EnsureNotDisposed(); return keyName; @@ -1002,7 +604,7 @@ namespace Microsoft.Win32 * error, and depending on the error, insert a string into the message * gotten from the ResourceManager. */ - internal void Win32Error(int errorCode, String str) + internal void Win32Error(int errorCode, string str) { switch (errorCode) { @@ -1011,27 +613,6 @@ namespace Microsoft.Win32 throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_RegistryKeyGeneric_Key, str)); else throw new UnauthorizedAccessException(); - - case Win32Native.ERROR_INVALID_HANDLE: - /** - * For normal RegistryKey instances we dispose the SafeRegHandle and throw IOException. - * However, for HKEY_PERFORMANCE_DATA (on a local or remote machine) we avoid disposing the - * SafeRegHandle and only throw the IOException. This is to workaround reentrancy issues - * in PerformanceCounter.NextValue() where the API could throw {NullReference, ObjectDisposed, ArgumentNull}Exception - * on reentrant calls because of this error code path in RegistryKey - * - * Normally we'd make our caller synchronize access to a shared RegistryKey instead of doing something like this, - * however we shipped PerformanceCounter.NextValue() un-synchronized in v2.0RTM and customers have taken a dependency on - * this behavior (being able to simultaneously query multiple remote-machine counters on multiple threads, instead of - * having serialized access). - */ - if (!IsPerfDataKey()) - { - hkey.SetHandleAsInvalid(); - hkey = null; - } - goto default; - case Win32Native.ERROR_FILE_NOT_FOUND: throw new IOException(SR.Arg_RegKeyNotFound, errorCode); @@ -1040,76 +621,6 @@ namespace Microsoft.Win32 } } - internal static String FixupName(String name) - { - BCLDebug.Assert(name != null, "[FixupName]name!=null"); - if (name.IndexOf('\\') == -1) - return name; - - StringBuilder sb = new StringBuilder(name); - FixupPath(sb); - int temp = sb.Length - 1; - if (temp >= 0 && sb[temp] == '\\') // Remove trailing slash - sb.Length = temp; - return sb.ToString(); - } - - - private static void FixupPath(StringBuilder path) - { - Contract.Requires(path != null); - int length = path.Length; - bool fixup = false; - char markerChar = (char)0xFFFF; - - int i = 1; - while (i < length - 1) - { - if (path[i] == '\\') - { - i++; - while (i < length) - { - if (path[i] == '\\') - { - path[i] = markerChar; - i++; - fixup = true; - } - else - break; - } - } - i++; - } - - if (fixup) - { - i = 0; - int j = 0; - while (i < length) - { - if (path[i] == markerChar) - { - i++; - continue; - } - path[j] = path[i]; - i++; - j++; - } - path.Length += j - i; - } - } - - private bool ContainsRegistryValue(string name) - { - int type = 0; - int datasize = 0; - int retval = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); - return retval == 0; - } - private void EnsureNotDisposed() { if (hkey == null) @@ -1127,41 +638,8 @@ namespace Microsoft.Win32 } } - private static int GetRegistryKeyAccess(bool isWritable) - { - int winAccess; - if (!isWritable) - { - winAccess = Win32Native.KEY_READ; - } - else - { - winAccess = Win32Native.KEY_READ | Win32Native.KEY_WRITE; - } - - return winAccess; - } - - private RegistryKeyPermissionCheck GetSubKeyPermissonCheck(bool subkeyWritable) - { - if (checkMode == RegistryKeyPermissionCheck.Default) - { - return checkMode; - } - - if (subkeyWritable) - { - return RegistryKeyPermissionCheck.ReadWriteSubTree; - } - else - { - return RegistryKeyPermissionCheck.ReadSubTree; - } - } - static private void ValidateKeyName(string name) { - Contract.Ensures(name != null); if (name == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); @@ -1182,33 +660,9 @@ namespace Microsoft.Win32 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug); } - static private void ValidateKeyView(RegistryView view) - { - if (view != RegistryView.Default && view != RegistryView.Registry32 && view != RegistryView.Registry64) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidRegistryViewCheck, ExceptionArgument.view); - } - } - // Win32 constants for error handling private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; } - - [Flags] - internal enum RegistryValueOptions - { - None = 0, - DoNotExpandEnvironmentNames = 1 - } - - // the name for this API is meant to mimic FileMode, which has similar values - - internal enum RegistryKeyPermissionCheck - { - Default = 0, - ReadSubTree = 1, - ReadWriteSubTree = 2 - } } diff --git a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs b/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs index 6e2a4f3..90c880b 100644 --- a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs +++ b/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace Microsoft.Win32 { internal enum RegistryValueKind @@ -13,8 +12,11 @@ namespace Microsoft.Win32 DWord = Win32Native.REG_DWORD, MultiString = Win32Native.REG_MULTI_SZ, QWord = Win32Native.REG_QWORD, - Unknown = 0, // REG_NONE is defined as zero but BCL - None = unchecked((int)0xFFFFFFFF), // mistakingly overrode this value. - } // Now instead of using Win32Native.REG_NONE we use "-1" and play games internally. + Unknown = 0, + + // REG_NONE is defined as zero but BCL, mistakingly overrode this value. + // Now instead of using Win32Native.REG_NONE we use "-1" and play games internally. + None = unchecked((int)0xFFFFFFFF), + } } diff --git a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryView.cs b/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryView.cs deleted file mode 100644 index e415865..0000000 --- a/src/coreclr/src/mscorlib/src/Microsoft/Win32/RegistryView.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// -// -// Implements Microsoft.Win32.RegistryView -// -// ====================================================================================== - -using System; - -namespace Microsoft.Win32 -{ - internal enum RegistryView - { - Default = 0, // 0x0000 operate on the default registry view - Registry64 = Win32Native.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view - Registry32 = Win32Native.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view - }; -} diff --git a/src/coreclr/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs b/src/coreclr/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs index 64dbb2c..1215000 100644 --- a/src/coreclr/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs +++ b/src/coreclr/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs @@ -2,19 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// -// -// -// Implements Microsoft.Win32.SafeHandles.SafeRegistryHandle -// -// ====================================================================================== - using System; using System.Security; using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Runtime.ConstrainedExecution; -using System.Runtime.Versioning; namespace Microsoft.Win32.SafeHandles { diff --git a/src/coreclr/src/mscorlib/src/System/Environment.cs b/src/coreclr/src/mscorlib/src/System/Environment.cs index 062e5d9..b981601 100644 --- a/src/coreclr/src/mscorlib/src/System/Environment.cs +++ b/src/coreclr/src/mscorlib/src/System/Environment.cs @@ -820,7 +820,7 @@ namespace System } else { - environmentKey.SetValue(variable, value); + environmentKey.SetStringValue(variable, value); } } } diff --git a/src/coreclr/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs b/src/coreclr/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs index 869b809..4ba95c8 100644 --- a/src/coreclr/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs +++ b/src/coreclr/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs @@ -42,54 +42,41 @@ namespace System.Globalization int hijriAdvance = 0; Microsoft.Win32.RegistryKey key = null; - try + using (key = Registry.CurrentUser.OpenSubKey(InternationalRegKey, writable: false)) { - // Open in read-only mode. - // Use InternalOpenSubKey so that we avoid the security check. - key = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER).OpenSubKey(InternationalRegKey, false); - } - //If this fails for any reason, we'll just return 0. - catch (ObjectDisposedException) { return 0; } - catch (ArgumentException) { return 0; } + if (key == null) + return 0; - if (key != null) - { - try + Object value = key.GetValue(HijriAdvanceRegKeyEntry); + if (value == null) { - Object value = key.InternalGetValue(HijriAdvanceRegKeyEntry, null, false, false); - if (value == null) - { - return (0); - } - String str = value.ToString(); - if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0) + return (0); + } + String str = value.ToString(); + if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0) + { + if (str.Length == HijriAdvanceRegKeyEntry.Length) + hijriAdvance = -1; + else { - if (str.Length == HijriAdvanceRegKeyEntry.Length) - hijriAdvance = -1; - else + str = str.Substring(HijriAdvanceRegKeyEntry.Length); + try { - str = str.Substring(HijriAdvanceRegKeyEntry.Length); - try + int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture); + if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri)) { - int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture); - if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri)) - { - hijriAdvance = advance; - } + hijriAdvance = advance; } - // If we got garbage from registry just ignore it. - // hijriAdvance = 0 because of declaraction assignment up above. - catch (ArgumentException) { } - catch (FormatException) { } - catch (OverflowException) { } } + // If we got garbage from registry just ignore it. + // hijriAdvance = 0 because of declaraction assignment up above. + catch (ArgumentException) { } + catch (FormatException) { } + catch (OverflowException) { } } } - finally - { - key.Close(); - } } + return (hijriAdvance); } } diff --git a/src/coreclr/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs b/src/coreclr/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs index a83c4fa..fe8b1b5 100644 --- a/src/coreclr/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs +++ b/src/coreclr/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs @@ -36,30 +36,30 @@ namespace System.Globalization try { - // Need to access registry - RegistryKey key = RegistryKey.GetBaseKey(RegistryKey.HKEY_LOCAL_MACHINE).OpenSubKey(c_japaneseErasHive, false); - - // Abort if we didn't find anything - if (key == null) return null; - - // Look up the values in our reg key - String[] valueNames = key.GetValueNames(); - if (valueNames != null && valueNames.Length > 0) + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(c_japaneseErasHive, writable: false)) { - registryEraRanges = new EraInfo[valueNames.Length]; + // Abort if we didn't find anything + if (key == null) return null; - // Loop through the registry and read in all the values - for (int i = 0; i < valueNames.Length; i++) + // Look up the values in our reg key + String[] valueNames = key.GetValueNames(); + if (valueNames != null && valueNames.Length > 0) { - // See if the era is a valid date - EraInfo era = GetEraFromValue(valueNames[i], key.GetValue(valueNames[i]).ToString()); + registryEraRanges = new EraInfo[valueNames.Length]; + + // Loop through the registry and read in all the values + for (int i = 0; i < valueNames.Length; i++) + { + // See if the era is a valid date + EraInfo era = GetEraFromValue(valueNames[i], key.GetValue(valueNames[i]).ToString()); - // continue if not valid - if (era == null) continue; + // continue if not valid + if (era == null) continue; - // Remember we found one. - registryEraRanges[iFoundEras] = era; - iFoundEras++; + // Remember we found one. + registryEraRanges[iFoundEras] = era; + iFoundEras++; + } } } } diff --git a/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.Win32.cs b/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.Win32.cs index f359a2a..b6585bd 100644 --- a/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.Win32.cs +++ b/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.Win32.cs @@ -576,8 +576,8 @@ namespace System // read LastEntry {(yearN, 1, 1) - MaxValue } // read the FirstEntry and LastEntry key values (ex: "1980", "2038") - int first = (int)dynamicKey.GetValue(FirstEntryValue, -1, RegistryValueOptions.None); - int last = (int)dynamicKey.GetValue(LastEntryValue, -1, RegistryValueOptions.None); + int first = (int)dynamicKey.GetValue(FirstEntryValue, -1); + int last = (int)dynamicKey.GetValue(LastEntryValue, -1); if (first == -1 || last == -1 || first > last) { @@ -587,7 +587,7 @@ namespace System // read the first year entry Win32Native.RegistryTimeZoneInformation dtzi; - byte[] regValue = dynamicKey.GetValue(first.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[]; + byte[] regValue = dynamicKey.GetValue(first.ToString(CultureInfo.InvariantCulture)) as byte[]; if (regValue == null || regValue.Length != RegByteLength) { rules = null; @@ -620,7 +620,7 @@ namespace System // read the middle year entries for (int i = first + 1; i < last; i++) { - regValue = dynamicKey.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[]; + regValue = dynamicKey.GetValue(i.ToString(CultureInfo.InvariantCulture)) as byte[]; if (regValue == null || regValue.Length != RegByteLength) { rules = null; @@ -640,7 +640,7 @@ namespace System } // read the last year entry - regValue = dynamicKey.GetValue(last.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[]; + regValue = dynamicKey.GetValue(last.ToString(CultureInfo.InvariantCulture)) as byte[]; dtzi = new Win32Native.RegistryTimeZoneInformation(regValue); if (regValue == null || regValue.Length != RegByteLength) { @@ -719,7 +719,7 @@ namespace System } Win32Native.RegistryTimeZoneInformation registryTimeZoneInfo; - byte[] regValue = key.GetValue(TimeZoneInfoValue, null, RegistryValueOptions.None) as byte[]; + byte[] regValue = key.GetValue(TimeZoneInfoValue) as byte[]; if (regValue == null || regValue.Length != RegByteLength) return false; registryTimeZoneInfo = new Win32Native.RegistryTimeZoneInformation(regValue); @@ -756,7 +756,7 @@ namespace System // if (result) { - string registryStandardName = key.GetValue(StandardValue, string.Empty, RegistryValueOptions.None) as string; + string registryStandardName = key.GetValue(StandardValue, string.Empty) as string; result = string.Equals(registryStandardName, timeZone.StandardName, StringComparison.Ordinal); } return result; @@ -884,9 +884,9 @@ namespace System daylightName = string.Empty; // read the MUI_ registry keys - string displayNameMuiResource = key.GetValue(MuiDisplayValue, string.Empty, RegistryValueOptions.None) as string; - string standardNameMuiResource = key.GetValue(MuiStandardValue, string.Empty, RegistryValueOptions.None) as string; - string daylightNameMuiResource = key.GetValue(MuiDaylightValue, string.Empty, RegistryValueOptions.None) as string; + string displayNameMuiResource = key.GetValue(MuiDisplayValue, string.Empty) as string; + string standardNameMuiResource = key.GetValue(MuiStandardValue, string.Empty) as string; + string daylightNameMuiResource = key.GetValue(MuiDaylightValue, string.Empty) as string; // try to load the strings from the native resource DLL(s) if (!string.IsNullOrEmpty(displayNameMuiResource)) @@ -907,15 +907,15 @@ namespace System // fallback to using the standard registry keys if (string.IsNullOrEmpty(displayName)) { - displayName = key.GetValue(DisplayValue, string.Empty, RegistryValueOptions.None) as string; + displayName = key.GetValue(DisplayValue, string.Empty) as string; } if (string.IsNullOrEmpty(standardName)) { - standardName = key.GetValue(StandardValue, string.Empty, RegistryValueOptions.None) as string; + standardName = key.GetValue(StandardValue, string.Empty) as string; } if (string.IsNullOrEmpty(daylightName)) { - daylightName = key.GetValue(DaylightValue, string.Empty, RegistryValueOptions.None) as string; + daylightName = key.GetValue(DaylightValue, string.Empty) as string; } return true; @@ -964,7 +964,7 @@ namespace System } Win32Native.RegistryTimeZoneInformation defaultTimeZoneInformation; - byte[] regValue = key.GetValue(TimeZoneInfoValue, null, RegistryValueOptions.None) as byte[]; + byte[] regValue = key.GetValue(TimeZoneInfoValue) as byte[]; if (regValue == null || regValue.Length != RegByteLength) { // the registry value could not be cast to a byte array -- 2.7.4