diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-04-13 14:17:19 +0900 |
commit | a56e30c8d33048216567753d9d3fefc2152af8ac (patch) | |
tree | 7e5d979695fc4a431740982eb1cfecc2898b23a5 /src/mscorlib/src/Microsoft | |
parent | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (diff) | |
download | coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.gz coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.bz2 coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.zip |
Imported Upstream version 2.0.0.11353upstream/2.0.0.11353
Diffstat (limited to 'src/mscorlib/src/Microsoft')
12 files changed, 766 insertions, 1377 deletions
diff --git a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs index 6c2c6e9630..93138e6e16 100644 --- a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs +++ b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs @@ -12,8 +12,9 @@ ** ** ===========================================================*/ -namespace Microsoft.Win32 { - + +namespace Microsoft.Win32 +{ using System; using System.Diagnostics.Contracts; using System.Reflection; @@ -31,8 +32,8 @@ namespace Microsoft.Win32 { public const int NoUserOverride = 0x04; public const int CalendarHijri = 0x08; public const int LocalBool = 0x10; - - internal static readonly Type [] ClassTypes = { + + internal static readonly Type[] ClassTypes = { typeof(Empty), typeof(void), typeof(Boolean), @@ -58,12 +59,12 @@ namespace Microsoft.Win32 { typeof(DBNull), }; - // Keep these numbers in sync w/ the above array. - private const int CV_OBJECT=0x12; - + // Keep these numbers in sync w/ the above array. + private const int CV_OBJECT = 0x12; + #endregion - + #region Internal Methods /** @@ -79,43 +80,45 @@ namespace Microsoft.Win32 { throw new ArgumentNullException(nameof(targetClass)); if (culture == null) throw new ArgumentNullException(nameof(culture)); - Variant result = new Variant (); - ChangeTypeEx(ref result, ref source, + Variant result = new Variant(); + ChangeTypeEx(ref result, ref source, #if FEATURE_USE_LCID - culture.LCID, + culture.LCID, #else // @CORESYSTODO: what does CoreSystem expect for this argument? 0, #endif targetClass.TypeHandle.Value, GetCVTypeFromClass(targetClass), options); return result; - } + } #endregion #region Private Helpers - private static int GetCVTypeFromClass(Type ctype) + private static int GetCVTypeFromClass(Type ctype) { Contract.Requires(ctype != null); #if _DEBUG BCLDebug.Assert(ClassTypes[CV_OBJECT] == typeof(Object), "OAVariantLib::ClassTypes[CV_OBJECT] == Object.class"); #endif - - int cvtype=-1; - for (int i=0; i<ClassTypes.Length; i++) { - if (ctype.Equals(ClassTypes[i])) { - cvtype=i; + + int cvtype = -1; + for (int i = 0; i < ClassTypes.Length; i++) + { + if (ctype.Equals(ClassTypes[i])) + { + cvtype = i; break; } } - + // OleAut Binder works better if unrecognized // types were changed to Object. So don't throw here. if (cvtype == -1) cvtype = CV_OBJECT; - + return cvtype; } diff --git a/src/mscorlib/src/Microsoft/Win32/Registry.cs b/src/mscorlib/src/Microsoft/Win32/Registry.cs index bf4f73949a..aa2dd9b396 100644 --- a/src/mscorlib/src/Microsoft/Win32/Registry.cs +++ b/src/mscorlib/src/Microsoft/Win32/Registry.cs @@ -2,133 +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. - -namespace Microsoft.Win32 { - using System; - using System.Runtime.InteropServices; - using System.Runtime.Versioning; - - /** - * 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 { - static 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(Environment.GetResourceString("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(); - } - } +namespace Microsoft.Win32 +{ + internal static class Registry + { + public static readonly RegistryKey CurrentUser = RegistryKey.CurrentUser; + public static readonly RegistryKey LocalMachine = RegistryKey.LocalMachine; } } diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs index f82b276059..e39b95903e 100644 --- a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs +++ b/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 @@ -48,70 +26,41 @@ */ +using Microsoft.Win32.SafeHandles; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; namespace Microsoft.Win32 { - using System; - using System.Collections; - using System.Collections.Generic; - using System.Security; - using System.Text; - using System.Threading; - using System.IO; - using System.Runtime.Remoting; - using System.Runtime.InteropServices; - using Microsoft.Win32.SafeHandles; - using System.Runtime.Versioning; - using System.Globalization; - using System.Diagnostics.Contracts; - using System.Diagnostics.CodeAnalysis; - /** * 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 + 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". // - private const int STATE_SYSTEMKEY = 0x0002; + private const int STATE_SYSTEMKEY = 0x0002; // Access // - 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", - }; + private const int STATE_WRITEACCESS = 0x0004; // MSDN defines the following limits for registry key names & values: // Key Name: 255 characters @@ -122,30 +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. @@ -156,37 +82,32 @@ 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; - this.keyName = ""; - this.remoteKey = remoteKey; - this.regView = view; - if (systemkey) { - this.state |= STATE_SYSTEMKEY; + keyName = ""; + if (systemkey) + { + state |= STATE_SYSTEMKEY; } - if (writable) { - this.state |= STATE_WRITEACCESS; + if (writable) + { + state |= STATE_WRITEACCESS; } - if (isPerfData) - this.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) { - if (hkey != null) { - - if (!IsSystemKey()) { - try { + private void Dispose(bool disposing) + { + if (hkey != null) + { + if (!IsSystemKey()) + { + try + { hkey.Dispose(); } - catch (IOException){ + catch (IOException) + { // we don't really care if the handle is invalid at this point } finally @@ -194,20 +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); - } } } @@ -216,278 +123,199 @@ namespace Microsoft.Win32 Dispose(true); } - public void DeleteValue(String name, bool throwOnMissingValue) { + public void DeleteValue(string name, bool throwOnMissingValue) + { EnsureWriteable(); - CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default); 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) { - if (throwOnMissingValue) { - ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent); + if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) + { + if (throwOnMissingValue) + { + 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) { - - 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); + private static RegistryKey GetBaseKey(IntPtr hKey, string keyName) + { + 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 <b>true</b>, then the subkey is opened with - * read-only access. - * - * @param name Name or path of subkey to open. - * @param readonly Set to <b>true</b> if you only need readonly access. - * - * @return the Subkey requested, or <b>null</b> if the operation failed. - */ - public RegistryKey OpenSubKey(string name, bool writable ) { + /// <summary> + /// Retrieves a subkey or null if the operation failed. + /// </summary> + /// <param name="writable">True to open writable, otherwise opens the key read-only.</param> + public RegistryKey OpenSubKey(string name, bool writable) + { ValidateKeyName(name); EnsureNotDisposed(); - name = FixupName(name); // Fixup multiple slashes to a single slash - CheckPermission(RegistryInternalCheck.CheckOpenSubKeyWithWritablePermission, name, writable, RegistryKeyPermissionCheck.Default); 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); + if (ret == 0 && !result.IsInvalid) + { + RegistryKey key = new RegistryKey(result, writable, false); key.keyName = keyName + "\\" + name; return key; } // Return null if we didn't find the key. - if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) { + if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) + { // We need to throw SecurityException here for compatibility reasons, // although UnauthorizedAccessException will make more sense. ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission); } - - 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 <b>null</b> if the operation failed. - */ - public RegistryKey OpenSubKey(String name) { - return OpenSubKey(name, false); - } - - internal int InternalSubKeyCount() { - EnsureNotDisposed(); - - int subkeys = 0; - int junk = 0; - int ret = Win32Native.RegQueryInfoKey(hkey, - null, - null, - IntPtr.Zero, - ref subkeys, // subkeys - null, - null, - ref junk, // values - null, - null, - null, - null); - - if (ret != 0) - Win32Error(ret, null); - return subkeys; - } - - /** - * Retrieves an array of strings containing all the subkey names. - * - * @return all subkey names. - */ - public String[] GetSubKeyNames() { - CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); - return InternalGetSubKeyNames(); - } - - internal unsafe String[] InternalGetSubKeyNames() { + /// <summary> + /// Retrieves an array of strings containing all the subkey names. + /// </summary> + public string[] GetSubKeyNames() + { EnsureNotDisposed(); - int subkeys = InternalSubKeyCount(); - String[] names = new String[subkeys]; // Returns 0-length array if empty. - if (subkeys > 0) { - char[] name = new char[MaxKeyLength + 1]; - - int namelen; + var names = new List<string>(); + char[] name = ArrayPool<char>.Shared.Rent(MaxKeyLength + 1); - fixed (char *namePtr = &name[0]) + try + { + int result; + int nameLength = name.Length; + + while ((result = Win32Native.RegEnumKeyEx( + hkey, + names.Count, + name, + ref nameLength, + null, + null, + null, + null)) != Interop.Errors.ERROR_NO_MORE_ITEMS) { - for (int i=0; i<subkeys; i++) { - namelen = name.Length; // Don't remove this. The API's doesn't work if this is not properly initialised. - int ret = Win32Native.RegEnumKeyEx(hkey, - i, - namePtr, - ref namelen, - null, - null, - null, - null); - if (ret != 0) - Win32Error(ret, null); - names[i] = new String(namePtr); + switch (result) + { + case Interop.Errors.ERROR_SUCCESS: + names.Add(new string(name, 0, nameLength)); + nameLength = name.Length; + break; + default: + // Throw the error + Win32Error(result, null); + break; } } } + finally + { + ArrayPool<char>.Shared.Return(name); + } - return names; + return names.ToArray(); } - internal int InternalValueCount() { - EnsureNotDisposed(); - int values = 0; - int junk = 0; - int ret = Win32Native.RegQueryInfoKey(hkey, - null, - null, - IntPtr.Zero, - ref junk, // subkeys - null, - null, - ref values, // values - null, - null, - null, - null); - if (ret != 0) - Win32Error(ret, null); - return values; - } - - /** - * Retrieves an array of strings containing all the value names. - * - * @return all value names. - */ - public unsafe String[] GetValueNames() { - CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default); + /// <summary> + /// Retrieves an array of strings containing all the value names. + /// </summary> + public unsafe string[] GetValueNames() + { EnsureNotDisposed(); + var names = new List<string>(); - int values = InternalValueCount(); - String[] names = new String[values]; + // Names in the registry aren't usually very long, although they can go to as large + // as 16383 characters (MaxValueLength). + // + // Every call to RegEnumValue will allocate another buffer to get the data from + // NtEnumerateValueKey before copying it back out to our passed in buffer. This can + // add up quickly- we'll try to keep the memory pressure low and grow the buffer + // only if needed. - if (values > 0) { - char[] name = new char[MaxValueLength + 1]; - int namelen; + char[] name = ArrayPool<char>.Shared.Rent(100); - fixed (char *namePtr = &name[0]) + try + { + int result; + int nameLength = name.Length; + + while ((result = Win32Native.RegEnumValue( + hkey, + names.Count, + name, + ref nameLength, + IntPtr.Zero, + null, + null, + null)) != Interop.Errors.ERROR_NO_MORE_ITEMS) { - for (int i=0; i<values; i++) { - namelen = name.Length; - - int ret = Win32Native.RegEnumValue(hkey, - i, - namePtr, - ref namelen, - IntPtr.Zero, - null, - null, - null); - - if (ret != 0) { - // ignore ERROR_MORE_DATA if we're querying HKEY_PERFORMANCE_DATA - if (!(IsPerfDataKey() && ret == Win32Native.ERROR_MORE_DATA)) - Win32Error(ret, null); - } - - names[i] = new String(namePtr); + switch (result) + { + // The size is only ever reported back correctly in the case + // of ERROR_SUCCESS. It will almost always be changed, however. + case Interop.Errors.ERROR_SUCCESS: + names.Add(new string(name, 0, nameLength)); + break; + case Interop.Errors.ERROR_MORE_DATA: + if (IsPerfDataKey()) + { + // Enumerating the values for Perf keys always returns + // ERROR_MORE_DATA, but has a valid name. Buffer does need + // to be big enough however. 8 characters is the largest + // known name. The size isn't returned, but the string is + // null terminated. + fixed (char* c = &name[0]) + { + names.Add(new string(c)); + } + } + else + { + char[] oldName = name; + int oldLength = oldName.Length; + name = null; + ArrayPool<char>.Shared.Return(oldName); + name = ArrayPool<char>.Shared.Rent(checked(oldLength * 2)); + } + break; + default: + // Throw the error + Win32Error(result, null); + break; } + + // Always set the name length back to the buffer size + nameLength = name.Length; } } + finally + { + if (name != null) + ArrayPool<char>.Shared.Return(name); + } - return names; - } - - /** - * Retrieves the specified value. <b>null</b> is returned if the value - * doesn't exist. - * - * Note that <var>name</var> 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) { - CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); - return InternalGetValue(name, null, false, true); + return names.ToArray(); } /** @@ -505,426 +333,257 @@ namespace Microsoft.Win32 * * @return the data associated with the value. */ - public Object GetValue(String name, Object defaultValue) { - CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); - 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(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options), nameof(options)); - } - bool doNotExpand = (options == RegistryValueOptions.DoNotExpandEnvironmentNames); - CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default); - return InternalGetValue(name, defaultValue, doNotExpand, true); - } - - internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity) { - if (checkSecurity) { - // Name can be null! It's the most common use of RegQueryValueEx - EnsureNotDisposed(); - } + public object GetValue(string name, object defaultValue = null, bool doNotExpand = false) + { + EnsureNotDisposed(); - Object data = defaultValue; + object data = defaultValue; int type = 0; int datasize = 0; int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize); - 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; - } + if (ret != 0) + { + // 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) { + 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: + case Win32Native.REG_DWORD_BIG_ENDIAN: + case Win32Native.REG_BINARY: + { + byte[] blob = new byte[datasize]; + ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); + data = blob; + } + break; + case Win32Native.REG_QWORD: + { // also REG_QWORD_LITTLE_ENDIAN + if (datasize > 8) + { + // prevent an AV in the edge case that datasize is larger than sizeof(long) + goto case Win32Native.REG_BINARY; + } + long blob = 0; + 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); - switch (type) { - case Win32Native.REG_NONE: - case Win32Native.REG_DWORD_BIG_ENDIAN: - case Win32Native.REG_BINARY: { - byte[] blob = new byte[datasize]; - ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); - data = blob; - } - break; - case Win32Native.REG_QWORD: - { // also REG_QWORD_LITTLE_ENDIAN - if (datasize > 8) { - // prevent an AV in the edge case that datasize is larger than sizeof(long) - goto case Win32Native.REG_BINARY; - } - long blob = 0; - BCLDebug.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); - - data = blob; - } - break; - case Win32Native.REG_DWORD: - { // also REG_DWORD_LITTLE_ENDIAN - if (datasize > 4) { - // prevent an AV in the edge case that datasize is larger than sizeof(int) - goto case Win32Native.REG_QWORD; - } - int blob = 0; - BCLDebug.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); - - data = blob; - } - break; - - case Win32Native.REG_SZ: - { - if (datasize % 2 == 1) { - // handle the case where the registry contains an odd-byte length (corrupt data?) - try { - datasize = checked(datasize + 1); - } - catch (OverflowException e) { - throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e); - } - } - char[] blob = new char[datasize/2]; - - 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); - } - 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); - } - } - break; - - case Win32Native.REG_EXPAND_SZ: - { - if (datasize % 2 == 1) { - // handle the case where the registry contains an odd-byte length (corrupt data?) - try { - datasize = checked(datasize + 1); - } - catch (OverflowException e) { - throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e); - } - } - char[] blob = new char[datasize/2]; - - 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); - } - 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); - } - - if (!doNotExpand) - data = Environment.ExpandEnvironmentVariables((String)data); - } - break; - case Win32Native.REG_MULTI_SZ: - { - if (datasize % 2 == 1) { - // handle the case where the registry contains an odd-byte length (corrupt data?) - try { - datasize = checked(datasize + 1); - } - catch (OverflowException e) { - throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e); - } - } - char[] blob = new char[datasize/2]; - - ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); - - // make sure the string is null terminated before processing the data - if (blob.Length > 0 && blob[blob.Length - 1] != (char)0) { - try { - char[] newBlob = new char[checked(blob.Length + 1)]; - for (int i = 0; i < blob.Length; i++) { - newBlob[i] = blob[i]; - } - newBlob[newBlob.Length - 1] = (char)0; - blob = newBlob; - } - catch (OverflowException e) { - throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e); - } - blob[blob.Length - 1] = (char)0; - } - - - IList<String> strings = new List<String>(); - int cur = 0; - int len = blob.Length; - - while (ret == 0 && cur < len) { - int nextNull = cur; - while (nextNull < len && blob[nextNull] != (char)0) { - nextNull++; - } - - if (nextNull < len) { - BCLDebug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0"); - if (nextNull-cur > 0) { - 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); - } - } - else { - strings.Add(new String(blob, cur, len-cur)); - } - cur = nextNull+1; - } - - data = new String[strings.Count]; - strings.CopyTo((String[])data, 0); - } - break; - case Win32Native.REG_LINK: - default: - break; - } - - return data; - } - - private bool IsSystemKey() { - return (this.state & STATE_SYSTEMKEY) != 0; - } - - private bool IsWritable() { - return (this.state & STATE_WRITEACCESS) != 0; - } - - private bool IsPerfDataKey() { - return (this.state & STATE_PERF_DATA) != 0; - } - - private void SetDirty() { - this.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); - } - - public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind) { - if (value==null) - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); + data = blob; + } + break; + case Win32Native.REG_DWORD: + { // also REG_DWORD_LITTLE_ENDIAN + if (datasize > 4) + { + // prevent an AV in the edge case that datasize is larger than sizeof(int) + goto case Win32Native.REG_QWORD; + } + int blob = 0; + 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); - if (name != null && name.Length > MaxValueLength) { - throw new ArgumentException(Environment.GetResourceString("Arg_RegValStrLenBug")); - } + data = blob; + } + break; - if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind)) - throw new ArgumentException(Environment.GetResourceString("Arg_RegBadKeyKind"), nameof(valueKind)); + case Win32Native.REG_SZ: + { + if (datasize % 2 == 1) + { + // handle the case where the registry contains an odd-byte length (corrupt data?) + try + { + datasize = checked(datasize + 1); + } + catch (OverflowException e) + { + throw new IOException(SR.Arg_RegGetOverflowBug, e); + } + } + char[] blob = new char[datasize / 2]; - EnsureWriteable(); + 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); + } + 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); + } + } + break; - if (!remoteKey && ContainsRegistryValue(name)) { // Existing key - CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default); - } - else { // Creating a new value - CheckPermission(RegistryInternalCheck.CheckValueCreatePermission, name, false, RegistryKeyPermissionCheck.Default); - } + case Win32Native.REG_EXPAND_SZ: + { + if (datasize % 2 == 1) + { + // handle the case where the registry contains an odd-byte length (corrupt data?) + try + { + datasize = checked(datasize + 1); + } + catch (OverflowException e) + { + throw new IOException(SR.Arg_RegGetOverflowBug, e); + } + } + char[] blob = new char[datasize / 2]; - 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); - } + ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); - int ret = 0; - try { - switch (valueKind) { - case RegistryValueKind.ExpandString: - case RegistryValueKind.String: + if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { - String data = value.ToString(); - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - valueKind, - data, - checked(data.Length * 2 + 2)); - break; + 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); } - case RegistryValueKind.MultiString: + if (!doNotExpand) + data = Environment.ExpandEnvironmentVariables((string)data); + } + break; + case Win32Native.REG_MULTI_SZ: + { + if (datasize % 2 == 1) { - // 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); + // handle the case where the registry contains an odd-byte length (corrupt data?) + try + { + datasize = checked(datasize + 1); + } + catch (OverflowException e) + { + throw new IOException(SR.Arg_RegGetOverflowBug, e); } - break; } + char[] blob = new char[datasize / 2]; - 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: + ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize); + + // make sure the string is null terminated before processing the data + if (blob.Length > 0 && blob[blob.Length - 1] != (char)0) { - // 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; + try + { + char[] newBlob = new char[checked(blob.Length + 1)]; + for (int i = 0; i < blob.Length; i++) + { + newBlob[i] = blob[i]; + } + newBlob[newBlob.Length - 1] = (char)0; + blob = newBlob; + } + catch (OverflowException e) + { + throw new IOException(SR.Arg_RegGetOverflowBug, e); + } + blob[blob.Length - 1] = (char)0; } - case RegistryValueKind.QWord: + IList<string> strings = new List<string>(); + int cur = 0; + int len = blob.Length; + + while (ret == 0 && cur < len) { - long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture); - - ret = Win32Native.RegSetValueEx(hkey, - name, - 0, - RegistryValueKind.QWord, - ref data, - 8); - break; + int nextNull = cur; + while (nextNull < len && blob[nextNull] != (char)0) + { + nextNull++; + } + + if (nextNull < len) + { + Debug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0"); + if (nextNull - cur > 0) + { + 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); + } + } + else + { + strings.Add(new string(blob, cur, len - cur)); + } + cur = nextNull + 1; } - } - } - 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(); + data = new string[strings.Count]; + strings.CopyTo((string[])data, 0); + } + break; + case Win32Native.REG_LINK: + default: + break; } - else - Win32Error(ret, null); + return data; + } + + private bool IsSystemKey() + { + return (state & STATE_SYSTEMKEY) != 0; } - 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(Environment.GetResourceString("Arg_RegSetBadArrType", value.GetType().Name)); + private bool IsWritable() + { + return (state & STATE_WRITEACCESS) != 0; + } + + private bool IsPerfDataKey() + { + return false; + } + + public unsafe void SetStringValue(string name, string value) + { + if (value == null) + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); + + if (name != null && name.Length > MaxValueLength) + { + throw new ArgumentException(SR.Arg_RegValStrLenBug); } - else - return RegistryValueKind.String; + + EnsureWriteable(); + + int result = Win32Native.RegSetValueEx(hkey, + name, + 0, + RegistryValueKind.String, + value, + checked(value.Length * 2 + 2)); + + if (result != 0) + Win32Error(result, null); } /** @@ -932,7 +591,8 @@ namespace Microsoft.Win32 * * @return a string representing the key. */ - public override String ToString() { + public override string ToString() + { EnsureNotDisposed(); return keyName; } @@ -944,164 +604,51 @@ 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) { - switch (errorCode) { + internal void Win32Error(int errorCode, string str) + { + switch (errorCode) + { case Win32Native.ERROR_ACCESS_DENIED: if (str != null) - throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_RegistryKeyGeneric_Key", str)); + 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()) { - this.hkey.SetHandleAsInvalid(); - this.hkey = null; - } - goto default; - case Win32Native.ERROR_FILE_NOT_FOUND: - throw new IOException(Environment.GetResourceString("Arg_RegKeyNotFound"), errorCode); + throw new IOException(SR.Arg_RegKeyNotFound, errorCode); default: throw new IOException(Win32Native.GetMessage(errorCode), errorCode); } } - 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) + private void EnsureNotDisposed() { - 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) + if (hkey == null) { - 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 void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck) - { - // TODO: Cleanup - } - - 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) { ThrowHelper.ThrowObjectDisposedException(keyName, ExceptionResource.ObjectDisposed_RegKeyClosed); } } - private void EnsureWriteable() { + private void EnsureWriteable() + { EnsureNotDisposed(); - if (!IsWritable()) { + if (!IsWritable()) + { ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource.UnauthorizedAccess_RegistryNoWrite); } } - 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) { + static private void ValidateKeyName(string name) + { + if (name == null) + { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } int nextSlash = name.IndexOf("\\", StringComparison.OrdinalIgnoreCase); int current = 0; - while (nextSlash != -1) { + while (nextSlash != -1) + { if ((nextSlash - current) > MaxKeyLength) ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug); @@ -1111,32 +658,11 @@ namespace Microsoft.Win32 if ((name.Length - current) > MaxKeyLength) 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_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/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs b/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs index 5e22275332..90c880b278 100644 --- a/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs +++ b/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs @@ -2,17 +2,21 @@ // 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 + { + String = Win32Native.REG_SZ, + ExpandString = Win32Native.REG_EXPAND_SZ, + Binary = Win32Native.REG_BINARY, + DWord = Win32Native.REG_DWORD, + MultiString = Win32Native.REG_MULTI_SZ, + QWord = Win32Native.REG_QWORD, + Unknown = 0, -namespace Microsoft.Win32 { - internal enum RegistryValueKind { - String = Win32Native.REG_SZ, - ExpandString = Win32Native.REG_EXPAND_SZ, - Binary = Win32Native.REG_BINARY, - 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. + // 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/mscorlib/src/Microsoft/Win32/RegistryView.cs b/src/mscorlib/src/Microsoft/Win32/RegistryView.cs deleted file mode 100644 index 302a603e0c..0000000000 --- a/src/mscorlib/src/Microsoft/Win32/RegistryView.cs +++ /dev/null @@ -1,19 +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 -// -// ====================================================================================== -namespace Microsoft.Win32 { - using System; - - 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/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs index 89ea22b855..d7d833d35d 100644 --- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs +++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs @@ -18,10 +18,11 @@ using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using Microsoft.Win32; -namespace Microsoft.Win32.SafeHandles { +namespace Microsoft.Win32.SafeHandles +{ internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid { - internal SafeFindHandle() : base(true) {} + internal SafeFindHandle() : base(true) { } override protected bool ReleaseHandle() { diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs index 603558c51a..256f611463 100644 --- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs +++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs @@ -2,11 +2,13 @@ // 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 { - using Microsoft.Win32.SafeHandles; +using Microsoft.Win32.SafeHandles; - sealed internal class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid { - internal SafeLibraryHandle() : base(true) {} +namespace Microsoft.Win32 +{ + sealed internal class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal SafeLibraryHandle() : base(true) { } override protected bool ReleaseHandle() { diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs index a1e5bc4263..1215000ec5 100644 --- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs +++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs @@ -2,28 +2,23 @@ // 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 -// -// ====================================================================================== -namespace Microsoft.Win32.SafeHandles { - using System; - using System.Security; - using System.Runtime.InteropServices; - using System.Runtime.CompilerServices; - using System.Runtime.ConstrainedExecution; - using System.Runtime.Versioning; +using System; +using System.Security; +using System.Runtime.InteropServices; - internal sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid { - internal SafeRegistryHandle() : base(true) {} +namespace Microsoft.Win32.SafeHandles +{ + internal sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid + { + internal SafeRegistryHandle() : base(true) { } - public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) { + public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) + { SetHandle(preexistingHandle); } - override protected bool ReleaseHandle() { + override protected bool ReleaseHandle() + { return (RegCloseKey(handle) == Win32Native.ERROR_SUCCESS); } diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs index 0ebcd5c09e..1141e6d027 100644 --- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs +++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs @@ -21,8 +21,8 @@ using System.Runtime.Versioning; using Microsoft.Win32; using System.Threading; -namespace Microsoft.Win32.SafeHandles { - +namespace Microsoft.Win32.SafeHandles +{ public sealed class SafeWaitHandle : SafeHandleZeroOrMinusOneIsInvalid { // Called by P/Invoke marshaler diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs index 62418131f3..8a7f591dfc 100644 --- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs +++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs @@ -13,17 +13,17 @@ // // +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Runtime.ConstrainedExecution; + namespace Microsoft.Win32.SafeHandles { - using System; - using System.Runtime.InteropServices; - using System.Runtime.CompilerServices; - using System.Runtime.ConstrainedExecution; - // Class of safe handle which uses 0 or -1 as an invalid handle. public abstract class SafeHandleZeroOrMinusOneIsInvalid : SafeHandle { - protected SafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) + protected SafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) { } @@ -33,7 +33,8 @@ namespace Microsoft.Win32.SafeHandles throw new NotImplementedException(); } - public override bool IsInvalid { + public override bool IsInvalid + { get { return handle.IsNull() || handle == new IntPtr(-1); } } } @@ -41,7 +42,7 @@ namespace Microsoft.Win32.SafeHandles // Class of safe handle which uses only -1 as an invalid handle. public abstract class SafeHandleMinusOneIsInvalid : SafeHandle { - protected SafeHandleMinusOneIsInvalid(bool ownsHandle) : base(new IntPtr(-1), ownsHandle) + protected SafeHandleMinusOneIsInvalid(bool ownsHandle) : base(new IntPtr(-1), ownsHandle) { } @@ -51,31 +52,8 @@ namespace Microsoft.Win32.SafeHandles throw new NotImplementedException(); } - public override bool IsInvalid { - get { return handle == new IntPtr(-1); } - } - } - - // Class of critical handle which uses 0 or -1 as an invalid handle. - public abstract class CriticalHandleZeroOrMinusOneIsInvalid : CriticalHandle - { - protected CriticalHandleZeroOrMinusOneIsInvalid() : base(IntPtr.Zero) - { - } - - public override bool IsInvalid { - get { return handle.IsNull() || handle == new IntPtr(-1); } - } - } - - // Class of critical handle which uses only -1 as an invalid handle. - public abstract class CriticalHandleMinusOneIsInvalid : CriticalHandle - { - protected CriticalHandleMinusOneIsInvalid() : base(new IntPtr(-1)) + public override bool IsInvalid { - } - - public override bool IsInvalid { get { return handle == new IntPtr(-1); } } } diff --git a/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs b/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs index 6e37b9c878..1b835d5dd1 100644 --- a/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs +++ b/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs @@ -2,7 +2,8 @@ // 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 { +namespace Microsoft.Win32 +{ using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System; @@ -16,12 +17,12 @@ namespace Microsoft.Win32 { using System.Diagnostics.Tracing; [SuppressUnmanagedCodeSecurityAttribute()] - internal static class UnsafeNativeMethods { - - [DllImport(Win32Native.KERNEL32, EntryPoint="GetTimeZoneInformation", SetLastError = true, ExactSpelling = true)] + internal static class UnsafeNativeMethods + { + [DllImport(Win32Native.KERNEL32, EntryPoint = "GetTimeZoneInformation", SetLastError = true, ExactSpelling = true)] internal static extern int GetTimeZoneInformation(out Win32Native.TimeZoneInformation lpTimeZoneInformation); - [DllImport(Win32Native.KERNEL32, EntryPoint="GetDynamicTimeZoneInformation", SetLastError = true, ExactSpelling = true)] + [DllImport(Win32Native.KERNEL32, EntryPoint = "GetDynamicTimeZoneInformation", SetLastError = true, ExactSpelling = true)] internal static extern int GetDynamicTimeZoneInformation(out Win32Native.DynamicTimeZoneInformation lpDynamicTimeZoneInformation); // @@ -35,7 +36,7 @@ namespace Microsoft.Win32 { // PULONGLONG pululEnumerator // ); // - [DllImport(Win32Native.KERNEL32, EntryPoint="GetFileMUIPath", SetLastError = true, ExactSpelling = true)] + [DllImport(Win32Native.KERNEL32, EntryPoint = "GetFileMUIPath", SetLastError = true, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetFileMUIPath( int flags, @@ -50,13 +51,13 @@ namespace Microsoft.Win32 { ref Int64 enumerator); - [DllImport(Win32Native.USER32, EntryPoint="LoadStringW", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] + [DllImport(Win32Native.USER32, EntryPoint = "LoadStringW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] internal static extern int LoadString(SafeLibraryHandle handle, int id, [Out] StringBuilder buffer, int bufferLength); - [DllImport(Win32Native.KERNEL32, CharSet=System.Runtime.InteropServices.CharSet.Unicode, SetLastError=true)] - internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags); - - [DllImport(Win32Native.KERNEL32, CharSet=System.Runtime.InteropServices.CharSet.Unicode)] + [DllImport(Win32Native.KERNEL32, CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true)] + internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags); + + [DllImport(Win32Native.KERNEL32, CharSet = System.Runtime.InteropServices.CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool FreeLibrary(IntPtr hModule); @@ -245,14 +246,13 @@ namespace Microsoft.Win32 { void* OutBuffer, int OutBufferSize, ref int ReturnLength); - } #if FEATURE_COMINTEROP [DllImport("combase.dll", PreserveSig = true)] internal static extern int RoGetActivationFactory( [MarshalAs(UnmanagedType.HString)] string activatableClassId, [In] ref Guid iid, - [Out,MarshalAs(UnmanagedType.IInspectable)] out Object factory); + [Out, MarshalAs(UnmanagedType.IInspectable)] out Object factory); #endif } diff --git a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs index b081b16ca1..8543bc8a99 100644 --- a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs +++ b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs @@ -87,7 +87,8 @@ * in your DllImportAttribute. */ -namespace Microsoft.Win32 { +namespace Microsoft.Win32 +{ using System; using System.Security; using System.Text; @@ -103,7 +104,7 @@ namespace Microsoft.Win32 { using BOOL = System.Int32; using DWORD = System.UInt32; using ULONG = System.UInt32; - + /** * Win32 encapsulation for MSCORLIB. */ @@ -111,49 +112,49 @@ namespace Microsoft.Win32 { // global declaration on the class. [SuppressUnmanagedCodeSecurityAttribute()] - internal static class Win32Native { - - internal const int KEY_QUERY_VALUE = 0x0001; - internal const int KEY_SET_VALUE = 0x0002; - internal const int KEY_CREATE_SUB_KEY = 0x0004; + internal static class Win32Native + { + internal const int KEY_QUERY_VALUE = 0x0001; + internal const int KEY_SET_VALUE = 0x0002; + internal const int KEY_CREATE_SUB_KEY = 0x0004; internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008; - internal const int KEY_NOTIFY = 0x0010; - internal const int KEY_CREATE_LINK = 0x0020; - internal const int KEY_READ =((STANDARD_RIGHTS_READ | - KEY_QUERY_VALUE | - KEY_ENUMERATE_SUB_KEYS | - KEY_NOTIFY) - & + internal const int KEY_NOTIFY = 0x0010; + internal const int KEY_CREATE_LINK = 0x0020; + internal const int KEY_READ = ((STANDARD_RIGHTS_READ | + KEY_QUERY_VALUE | + KEY_ENUMERATE_SUB_KEYS | + KEY_NOTIFY) + & (~SYNCHRONIZE)); - - internal const int KEY_WRITE =((STANDARD_RIGHTS_WRITE | - KEY_SET_VALUE | - KEY_CREATE_SUB_KEY) - & + + internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE | + KEY_SET_VALUE | + KEY_CREATE_SUB_KEY) + & (~SYNCHRONIZE)); - internal const int KEY_WOW64_64KEY = 0x0100; // - internal const int KEY_WOW64_32KEY = 0x0200; // - internal const int REG_OPTION_NON_VOLATILE= 0x0000; // (default) keys are persisted beyond reboot/unload - internal const int REG_OPTION_VOLATILE = 0x0001; // All keys created by the function are volatile + internal const int KEY_WOW64_64KEY = 0x0100; // + internal const int KEY_WOW64_32KEY = 0x0200; // + internal const int REG_OPTION_NON_VOLATILE = 0x0000; // (default) keys are persisted beyond reboot/unload + internal const int REG_OPTION_VOLATILE = 0x0001; // All keys created by the function are volatile internal const int REG_OPTION_CREATE_LINK = 0x0002; // They key is a symbolic link internal const int REG_OPTION_BACKUP_RESTORE = 0x0004; // Use SE_BACKUP_NAME process special privileges - internal const int REG_NONE = 0; // No value type - internal const int REG_SZ = 1; // Unicode nul terminated string - internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string + internal const int REG_NONE = 0; // No value type + internal const int REG_SZ = 1; // Unicode nul terminated string + internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string // (with environment variable references) - internal const int REG_BINARY = 3; // Free form binary - internal const int REG_DWORD = 4; // 32-bit number - internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD) - internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number - internal const int REG_LINK = 6; // Symbolic Link (unicode) - internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings - internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map - internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description - internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10; - internal const int REG_QWORD = 11; // 64-bit number - - internal const int HWND_BROADCAST = 0xffff; - internal const int WM_SETTINGCHANGE = 0x001A; + internal const int REG_BINARY = 3; // Free form binary + internal const int REG_DWORD = 4; // 32-bit number + internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD) + internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number + internal const int REG_LINK = 6; // Symbolic Link (unicode) + internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings + internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map + internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description + internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10; + internal const int REG_QWORD = 11; // 64-bit number + + internal const int HWND_BROADCAST = 0xffff; + internal const int WM_SETTINGCHANGE = 0x001A; // TimeZone internal const int TIME_ZONE_ID_INVALID = -1; @@ -174,7 +175,8 @@ namespace Microsoft.Win32 { internal const int LOAD_STRING_MAX_LENGTH = 500; [StructLayout(LayoutKind.Sequential)] - internal struct SystemTime { + internal struct SystemTime + { [MarshalAs(UnmanagedType.U2)] public short Year; [MarshalAs(UnmanagedType.U2)] @@ -194,7 +196,8 @@ namespace Microsoft.Win32 { } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct TimeZoneInformation { + internal struct TimeZoneInformation + { [MarshalAs(UnmanagedType.I4)] public Int32 Bias; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] @@ -208,7 +211,8 @@ namespace Microsoft.Win32 { [MarshalAs(UnmanagedType.I4)] public Int32 DaylightBias; - public TimeZoneInformation(Win32Native.DynamicTimeZoneInformation dtzi) { + public TimeZoneInformation(Win32Native.DynamicTimeZoneInformation dtzi) + { Bias = dtzi.Bias; StandardName = dtzi.StandardName; StandardDate = dtzi.StandardDate; @@ -221,7 +225,8 @@ namespace Microsoft.Win32 { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct DynamicTimeZoneInformation { + internal struct DynamicTimeZoneInformation + { [MarshalAs(UnmanagedType.I4)] public Int32 Bias; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] @@ -242,7 +247,8 @@ namespace Microsoft.Win32 { [StructLayout(LayoutKind.Sequential)] - internal struct RegistryTimeZoneInformation { + internal struct RegistryTimeZoneInformation + { [MarshalAs(UnmanagedType.I4)] public Int32 Bias; [MarshalAs(UnmanagedType.I4)] @@ -252,7 +258,8 @@ namespace Microsoft.Win32 { public SystemTime StandardDate; public SystemTime DaylightDate; - public RegistryTimeZoneInformation(Win32Native.TimeZoneInformation tzi) { + public RegistryTimeZoneInformation(Win32Native.TimeZoneInformation tzi) + { Bias = tzi.Bias; StandardDate = tzi.StandardDate; StandardBias = tzi.StandardBias; @@ -260,7 +267,8 @@ namespace Microsoft.Win32 { DaylightBias = tzi.DaylightBias; } - public RegistryTimeZoneInformation(Byte[] bytes) { + public RegistryTimeZoneInformation(Byte[] bytes) + { // // typedef struct _REG_TZI_FORMAT { // [00-03] LONG Bias; @@ -286,8 +294,9 @@ namespace Microsoft.Win32 { // [42-43] WORD wMilliseconds; // } REG_TZI_FORMAT; // - if (bytes == null || bytes.Length != 44) { - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidREG_TZI_FORMAT"), nameof(bytes)); + if (bytes == null || bytes.Length != 44) + { + throw new ArgumentException(SR.Argument_InvalidREG_TZI_FORMAT, nameof(bytes)); } Bias = BitConverter.ToInt32(bytes, 0); StandardBias = BitConverter.ToInt32(bytes, 4); @@ -317,12 +326,12 @@ namespace Microsoft.Win32 { // Win32 ACL-related constants: - internal const int READ_CONTROL = 0x00020000; - internal const int SYNCHRONIZE = 0x00100000; + internal const int READ_CONTROL = 0x00020000; + internal const int SYNCHRONIZE = 0x00100000; + + internal const int STANDARD_RIGHTS_READ = READ_CONTROL; + internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL; - internal const int STANDARD_RIGHTS_READ = READ_CONTROL; - internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL; - // STANDARD_RIGHTS_REQUIRED (0x000F0000L) // SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) @@ -332,18 +341,20 @@ namespace Microsoft.Win32 { // Note that you may need to specify the SYNCHRONIZE bit as well // to be able to open a synchronization primitive. internal const int SEMAPHORE_MODIFY_STATE = 0x00000002; - internal const int EVENT_MODIFY_STATE = 0x00000002; - internal const int MUTEX_MODIFY_STATE = 0x00000001; - internal const int MUTEX_ALL_ACCESS = 0x001F0001; + internal const int EVENT_MODIFY_STATE = 0x00000002; + internal const int MUTEX_MODIFY_STATE = 0x00000001; + internal const int MUTEX_ALL_ACCESS = 0x001F0001; - internal const int LMEM_FIXED = 0x0000; + internal const int LMEM_FIXED = 0x0000; internal const int LMEM_ZEROINIT = 0x0040; - internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT); + internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT); - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] - internal class OSVERSIONINFO { - internal OSVERSIONINFO() { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal class OSVERSIONINFO + { + internal OSVERSIONINFO() + { OSVersionInfoSize = (int)Marshal.SizeOf(this); } @@ -353,14 +364,15 @@ namespace Microsoft.Win32 { internal int MinorVersion = 0; internal int BuildNumber = 0; internal int PlatformId = 0; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] internal String CSDVersion = null; } - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] - internal class OSVERSIONINFOEX { - - public OSVERSIONINFOEX() { + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + internal class OSVERSIONINFOEX + { + public OSVERSIONINFOEX() + { OSVersionInfoSize = (int)Marshal.SizeOf(this); } @@ -370,26 +382,28 @@ namespace Microsoft.Win32 { internal int MinorVersion = 0; internal int BuildNumber = 0; internal int PlatformId = 0; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] internal string CSDVersion = null; internal ushort ServicePackMajor = 0; internal ushort ServicePackMinor = 0; internal short SuiteMask = 0; internal byte ProductType = 0; - internal byte Reserved = 0; + internal byte Reserved = 0; } [StructLayout(LayoutKind.Sequential)] - internal class SECURITY_ATTRIBUTES { + internal class SECURITY_ATTRIBUTES + { internal int nLength = 0; // don't remove null, or this field will disappear in bcl.small - internal unsafe byte * pSecurityDescriptor = null; + internal unsafe byte* pSecurityDescriptor = null; internal int bInheritHandle = 0; } [Serializable] [StructLayout(LayoutKind.Sequential)] - internal struct WIN32_FILE_ATTRIBUTE_DATA { + internal struct WIN32_FILE_ATTRIBUTE_DATA + { internal int fileAttributes; internal uint ftCreationTimeLow; internal uint ftCreationTimeHigh; @@ -400,22 +414,24 @@ namespace Microsoft.Win32 { internal int fileSizeHigh; internal int fileSizeLow; - internal void PopulateFrom(WIN32_FIND_DATA findData) { + internal void PopulateFrom(WIN32_FIND_DATA findData) + { // Copy the information to data - fileAttributes = findData.dwFileAttributes; - ftCreationTimeLow = findData.ftCreationTime_dwLowDateTime; - ftCreationTimeHigh = findData.ftCreationTime_dwHighDateTime; - ftLastAccessTimeLow = findData.ftLastAccessTime_dwLowDateTime; - ftLastAccessTimeHigh = findData.ftLastAccessTime_dwHighDateTime; - ftLastWriteTimeLow = findData.ftLastWriteTime_dwLowDateTime; - ftLastWriteTimeHigh = findData.ftLastWriteTime_dwHighDateTime; - fileSizeHigh = findData.nFileSizeHigh; - fileSizeLow = findData.nFileSizeLow; + fileAttributes = findData.dwFileAttributes; + ftCreationTimeLow = findData.ftCreationTime_dwLowDateTime; + ftCreationTimeHigh = findData.ftCreationTime_dwHighDateTime; + ftLastAccessTimeLow = findData.ftLastAccessTime_dwLowDateTime; + ftLastAccessTimeHigh = findData.ftLastAccessTime_dwHighDateTime; + ftLastWriteTimeLow = findData.ftLastWriteTime_dwLowDateTime; + ftLastWriteTimeHigh = findData.ftLastWriteTime_dwHighDateTime; + fileSizeHigh = findData.nFileSizeHigh; + fileSizeLow = findData.nFileSizeLow; } } [StructLayout(LayoutKind.Sequential)] - internal struct MEMORYSTATUSEX { + internal struct MEMORYSTATUSEX + { // The length field must be set to the size of this data structure. internal int length; internal int memoryLoad; @@ -429,7 +445,8 @@ namespace Microsoft.Win32 { } [StructLayout(LayoutKind.Sequential)] - internal unsafe struct MEMORY_BASIC_INFORMATION { + internal unsafe struct MEMORY_BASIC_INFORMATION + { internal void* BaseAddress; internal void* AllocationBase; internal uint AllocationProtect; @@ -441,10 +458,10 @@ namespace Microsoft.Win32 { #if !FEATURE_PAL internal const String KERNEL32 = "kernel32.dll"; - internal const String USER32 = "user32.dll"; - internal const String OLE32 = "ole32.dll"; + internal const String USER32 = "user32.dll"; + internal const String OLE32 = "ole32.dll"; internal const String OLEAUT32 = "oleaut32.dll"; - internal const String NTDLL = "ntdll.dll"; + internal const String NTDLL = "ntdll.dll"; #else //FEATURE_PAL internal const String KERNEL32 = "libcoreclr"; internal const String USER32 = "libcoreclr"; @@ -453,40 +470,43 @@ namespace Microsoft.Win32 { internal const String NTDLL = "libcoreclr"; #endif //FEATURE_PAL internal const String ADVAPI32 = "advapi32.dll"; - internal const String SHELL32 = "shell32.dll"; - internal const String SHIM = "mscoree.dll"; - internal const String CRYPT32 = "crypt32.dll"; - internal const String SECUR32 = "secur32.dll"; + internal const String SHELL32 = "shell32.dll"; + internal const String SHIM = "mscoree.dll"; + internal const String CRYPT32 = "crypt32.dll"; + internal const String SECUR32 = "secur32.dll"; internal const String MSCORWKS = "coreclr.dll"; // From WinBase.h internal const int SEM_FAILCRITICALERRORS = 1; - [DllImport(KERNEL32, CharSet=CharSet.Auto, BestFitMapping=true)] + [DllImport(KERNEL32, CharSet = CharSet.Auto, BestFitMapping = true)] internal static extern int FormatMessage(int dwFlags, IntPtr lpSource, int dwMessageId, int dwLanguageId, [Out]StringBuilder lpBuffer, int nSize, IntPtr va_list_arguments); // Gets an error message for a Win32 error code. - internal static String GetMessage(int errorCode) { + internal static String GetMessage(int errorCode) + { StringBuilder sb = StringBuilderCache.Acquire(512); int result = Win32Native.FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, IntPtr.Zero, errorCode, 0, sb, sb.Capacity, IntPtr.Zero); - if (result != 0) { + if (result != 0) + { // result is the # of characters copied to the StringBuilder. return StringBuilderCache.GetStringAndRelease(sb); } - else { + else + { StringBuilderCache.Release(sb); - return Environment.GetResourceString("UnknownError_Num", errorCode); + return SR.Format(SR.UnknownError_Num, errorCode); } } - [DllImport(KERNEL32, EntryPoint="LocalAlloc")] + [DllImport(KERNEL32, EntryPoint = "LocalAlloc")] internal static extern IntPtr LocalAlloc_NoSafeHandle(int uFlags, UIntPtr sizetdwBytes); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static extern IntPtr LocalFree(IntPtr handle); // MSDN says the length is a SIZE_T. @@ -499,25 +519,25 @@ namespace Microsoft.Win32 { return GlobalMemoryStatusExNative(ref buffer); } - [DllImport(KERNEL32, SetLastError=true, EntryPoint="GlobalMemoryStatusEx")] + [DllImport(KERNEL32, SetLastError = true, EntryPoint = "GlobalMemoryStatusEx")] private static extern bool GlobalMemoryStatusExNative([In, Out] ref MEMORYSTATUSEX buffer); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] unsafe internal static extern UIntPtr VirtualQuery(void* address, ref MEMORY_BASIC_INFORMATION buffer, UIntPtr sizeOfBuffer); // VirtualAlloc should generally be avoided, but is needed in // the MemoryFailPoint implementation (within a CER) to increase the // size of the page file, ignoring any host memory allocators. - [DllImport(KERNEL32, SetLastError=true)] - unsafe internal static extern void * VirtualAlloc(void* address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode); + [DllImport(KERNEL32, SetLastError = true)] + unsafe internal static extern void* VirtualAlloc(void* address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] unsafe internal static extern bool VirtualFree(void* address, UIntPtr numBytes, int pageFreeMode); - [DllImport(KERNEL32, CharSet=CharSet.Ansi, ExactSpelling=true, EntryPoint="lstrlenA")] + [DllImport(KERNEL32, CharSet = CharSet.Ansi, ExactSpelling = true, EntryPoint = "lstrlenA")] internal static extern int lstrlenA(IntPtr ptr); - [DllImport(KERNEL32, CharSet=CharSet.Unicode, ExactSpelling=true, EntryPoint="lstrlenW")] + [DllImport(KERNEL32, CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "lstrlenW")] internal static extern int lstrlenW(IntPtr ptr); [DllImport(Win32Native.OLEAUT32, CharSet = CharSet.Unicode)] @@ -538,31 +558,31 @@ namespace Microsoft.Win32 { #endif - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static extern bool SetEvent(SafeWaitHandle handle); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static extern bool ResetEvent(SafeWaitHandle handle); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern SafeWaitHandle CreateEvent(SECURITY_ATTRIBUTES lpSecurityAttributes, bool isManualReset, bool initialState, String name); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern SafeWaitHandle OpenEvent(/* DWORD */ int desiredAccess, bool inheritHandle, String name); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern SafeWaitHandle CreateMutex(SECURITY_ATTRIBUTES lpSecurityAttributes, bool initialOwner, String name); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern SafeWaitHandle OpenMutex(/* DWORD */ int desiredAccess, bool inheritHandle, String name); - - [DllImport(KERNEL32, SetLastError=true)] + + [DllImport(KERNEL32, SetLastError = true)] internal static extern bool ReleaseMutex(SafeWaitHandle handle); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static extern bool CloseHandle(IntPtr handle); - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static unsafe extern int WriteFile(SafeFileHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero); [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] @@ -576,13 +596,13 @@ namespace Microsoft.Win32 { internal static extern SafeWaitHandle OpenSemaphore(/* DWORD */ int desiredAccess, bool inheritHandle, String name); // Will be in winnls.h - internal const int FIND_STARTSWITH = 0x00100000; // see if value is at the beginning of source - internal const int FIND_ENDSWITH = 0x00200000; // see if value is at the end of source - internal const int FIND_FROMSTART = 0x00400000; // look for value in source, starting at the beginning - internal const int FIND_FROMEND = 0x00800000; // look for value in source, starting at the end + internal const int FIND_STARTSWITH = 0x00100000; // see if value is at the beginning of source + internal const int FIND_ENDSWITH = 0x00200000; // see if value is at the end of source + internal const int FIND_FROMSTART = 0x00400000; // look for value in source, starting at the beginning + internal const int FIND_FROMEND = 0x00800000; // look for value in source, starting at the end [StructLayout(LayoutKind.Sequential)] - internal struct NlsVersionInfoEx + internal struct NlsVersionInfoEx { internal int dwNLSVersionInfoSize; internal int dwNLSVersion; @@ -591,7 +611,7 @@ namespace Microsoft.Win32 { internal Guid guidCustomVersion; } - [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)] + [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] internal static extern int GetSystemDirectory([Out]StringBuilder sb, int length); internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); // WinBase.h @@ -601,7 +621,7 @@ namespace Microsoft.Win32 { internal const int STD_OUTPUT_HANDLE = -11; internal const int STD_ERROR_HANDLE = -12; - [DllImport(KERNEL32, SetLastError=true)] + [DllImport(KERNEL32, SetLastError = true)] internal static extern IntPtr GetStdHandle(int nStdHandle); // param is NOT a handle, but it returns one! // From wincon.h @@ -621,32 +641,32 @@ namespace Microsoft.Win32 { internal const int REPLACEFILE_IGNORE_MERGE_ERRORS = 0x2; private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; - private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; + private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; internal const uint FILE_MAP_WRITE = 0x0002; internal const uint FILE_MAP_READ = 0x0004; // Constants from WinNT.h - internal const int FILE_ATTRIBUTE_READONLY = 0x00000001; - internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; + internal const int FILE_ATTRIBUTE_READONLY = 0x00000001; + internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010; internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400; internal const int IO_REPARSE_TAG_MOUNT_POINT = unchecked((int)0xA0000003); internal const int PAGE_READWRITE = 0x04; - internal const int MEM_COMMIT = 0x1000; - internal const int MEM_RESERVE = 0x2000; - internal const int MEM_RELEASE = 0x8000; - internal const int MEM_FREE = 0x10000; + internal const int MEM_COMMIT = 0x1000; + internal const int MEM_RESERVE = 0x2000; + internal const int MEM_RELEASE = 0x8000; + internal const int MEM_FREE = 0x10000; // Error codes from WinError.h internal const int ERROR_SUCCESS = 0x0; internal const int ERROR_INVALID_FUNCTION = 0x1; internal const int ERROR_FILE_NOT_FOUND = 0x2; internal const int ERROR_PATH_NOT_FOUND = 0x3; - internal const int ERROR_ACCESS_DENIED = 0x5; + internal const int ERROR_ACCESS_DENIED = 0x5; internal const int ERROR_INVALID_HANDLE = 0x6; internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8; internal const int ERROR_INVALID_DATA = 0xd; @@ -699,10 +719,10 @@ namespace Microsoft.Win32 { internal const uint STATUS_INSUFFICIENT_RESOURCES = 0xC000009A; internal const uint STATUS_ACCESS_DENIED = 0xC0000022; - internal const int INVALID_FILE_SIZE = -1; + internal const int INVALID_FILE_SIZE = -1; // From WinStatus.h - internal const int STATUS_ACCOUNT_RESTRICTION = unchecked((int) 0xC000006E); + internal const int STATUS_ACCOUNT_RESTRICTION = unchecked((int)0xC000006E); // Use this to translate error codes like the above into HRESULTs like // 0x80070006 for ERROR_INVALID_HANDLE @@ -714,12 +734,13 @@ namespace Microsoft.Win32 { // Win32 Structs in N/Direct style [Serializable] - [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] [BestFitMapping(false)] - internal class WIN32_FIND_DATA { - internal int dwFileAttributes = 0; + internal class WIN32_FIND_DATA + { + internal int dwFileAttributes = 0; // ftCreationTime was a by-value FILETIME structure - internal uint ftCreationTime_dwLowDateTime = 0 ; + internal uint ftCreationTime_dwLowDateTime = 0; internal uint ftCreationTime_dwHighDateTime = 0; // ftLastAccessTime was a by-value FILETIME structure internal uint ftLastAccessTime_dwLowDateTime = 0; @@ -727,24 +748,24 @@ namespace Microsoft.Win32 { // ftLastWriteTime was a by-value FILETIME structure internal uint ftLastWriteTime_dwLowDateTime = 0; internal uint ftLastWriteTime_dwHighDateTime = 0; - internal int nFileSizeHigh = 0; - internal int nFileSizeLow = 0; + internal int nFileSizeHigh = 0; + internal int nFileSizeLow = 0; // If the file attributes' reparse point flag is set, then // dwReserved0 is the file tag (aka reparse tag) for the // reparse point. Use this to figure out whether something is // a volume mount point or a symbolic link. - internal int dwReserved0 = 0; - internal int dwReserved1 = 0; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] - internal String cFileName = null; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)] - internal String cAlternateFileName = null; + internal int dwReserved0 = 0; + internal int dwReserved1 = 0; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + internal String cFileName = null; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] + internal String cAlternateFileName = null; } - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] Win32Native.WIN32_FIND_DATA data); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern bool FindNextFile( SafeFindHandle hndFindFile, [In, Out, MarshalAs(UnmanagedType.LPStruct)] @@ -756,13 +777,13 @@ namespace Microsoft.Win32 { [DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)] internal static extern uint GetCurrentDirectoryW(uint nBufferLength, char[] lpBuffer); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern bool GetFileAttributesEx(String name, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation); - [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern bool SetCurrentDirectory(String path); - [DllImport(KERNEL32, SetLastError=false, EntryPoint="SetErrorMode", ExactSpelling=true)] + [DllImport(KERNEL32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)] private static extern int SetErrorMode_VistaAndOlder(int newMode); // RTM versions of Win7 and Windows Server 2008 R2 @@ -779,24 +800,21 @@ namespace Microsoft.Win32 { [DllImport(KERNEL32)] internal static extern unsafe int WideCharToMultiByte(uint cp, uint flags, char* pwzSource, int cchSource, byte* pbDestBuffer, int cbDestBuffer, IntPtr null1, IntPtr null2); - [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)] + [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] internal static extern bool SetEnvironmentVariable(string lpName, string lpValue); - - [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)] + + [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] internal static extern int GetEnvironmentVariable(string lpName, [Out]StringBuilder lpValue, int size); - [DllImport(KERNEL32, CharSet=CharSet.Unicode)] - internal static unsafe extern char * GetEnvironmentStrings(); + [DllImport(KERNEL32, CharSet = CharSet.Unicode)] + internal static unsafe extern char* GetEnvironmentStrings(); - [DllImport(KERNEL32, CharSet=CharSet.Unicode)] - internal static unsafe extern bool FreeEnvironmentStrings(char * pStrings); + [DllImport(KERNEL32, CharSet = CharSet.Unicode)] + internal static unsafe extern bool FreeEnvironmentStrings(char* pStrings); - [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true)] + [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)] internal static extern uint GetCurrentProcessId(); - [DllImport(KERNEL32, CharSet=CharSet.Auto, BestFitMapping=false)] - internal extern static int GetComputerName([Out]StringBuilder nameBuffer, ref int bufferSize); - [DllImport(OLE32)] internal extern static int CoCreateGuid(out Guid guid); @@ -810,148 +828,150 @@ namespace Microsoft.Win32 { internal static extern IntPtr CoTaskMemRealloc(IntPtr pv, UIntPtr cb); #if FEATURE_WIN32_REGISTRY - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegDeleteValue(SafeRegistryHandle hKey, String lpValueName); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal unsafe static extern int RegEnumKeyEx(SafeRegistryHandle hKey, int dwIndex, - char *lpName, ref int lpcbName, int[] lpReserved, + char[] lpName, ref int lpcbName, int[] lpReserved, [Out]StringBuilder lpClass, int[] lpcbClass, long[] lpftLastWriteTime); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal unsafe static extern int RegEnumValue(SafeRegistryHandle hKey, int dwIndex, - char *lpValueName, ref int lpcbValueName, + char[] lpValueName, ref int lpcbValueName, IntPtr lpReserved_MustBeZero, int[] lpType, byte[] lpData, int[] lpcbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegOpenKeyEx(SafeRegistryHandle hKey, String lpSubKey, int ulOptions, int samDesired, out SafeRegistryHandle hkResult); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegQueryInfoKey(SafeRegistryHandle hKey, [Out]StringBuilder lpClass, int[] lpcbClass, IntPtr lpReserved_MustBeZero, ref int lpcSubKeys, int[] lpcbMaxSubKeyLen, int[] lpcbMaxClassLen, ref int lpcValues, int[] lpcbMaxValueNameLen, int[] lpcbMaxValueLen, int[] lpcbSecurityDescriptor, int[] lpftLastWriteTime); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, int[] lpReserved, ref int lpType, [Out] byte[] lpData, ref int lpcbData); - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, int[] lpReserved, ref int lpType, ref int lpData, ref int lpcbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, int[] lpReserved, ref int lpType, ref long lpData, ref int lpcbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName, - int[] lpReserved, ref int lpType, [Out] char[] lpData, + int[] lpReserved, ref int lpType, [Out] char[] lpData, ref int lpcbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName, int Reserved, RegistryValueKind dwType, byte[] lpData, int cbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName, int Reserved, RegistryValueKind dwType, ref int lpData, int cbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName, int Reserved, RegistryValueKind dwType, ref long lpData, int cbData); - - [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)] + + [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)] internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName, int Reserved, RegistryValueKind dwType, String lpData, int cbData); #endif // FEATURE_WIN32_REGISTRY - - [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)] + + [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] internal static extern int ExpandEnvironmentStrings(String lpSrc, [Out]StringBuilder lpDst, int nSize); [DllImport(KERNEL32)] internal static extern IntPtr LocalReAlloc(IntPtr handle, IntPtr sizetcbBytes, int uFlags); - internal const int SHGFP_TYPE_CURRENT = 0; // the current (user) folder path setting - internal const int UOI_FLAGS = 1; - internal const int WSF_VISIBLE = 1; + internal const int SHGFP_TYPE_CURRENT = 0; // the current (user) folder path setting + internal const int UOI_FLAGS = 1; + internal const int WSF_VISIBLE = 1; // .NET Framework 4.0 and newer - all versions of windows ||| \public\sdk\inc\shlobj.h - internal const int CSIDL_FLAG_CREATE = 0x8000; // force folder creation in SHGetFolderPath - internal const int CSIDL_FLAG_DONT_VERIFY = 0x4000; // return an unverified folder path - internal const int CSIDL_ADMINTOOLS = 0x0030; // <user name>\Start Menu\Programs\Administrative Tools - internal const int CSIDL_CDBURN_AREA = 0x003b; // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning - internal const int CSIDL_COMMON_ADMINTOOLS = 0x002f; // All Users\Start Menu\Programs\Administrative Tools - internal const int CSIDL_COMMON_DOCUMENTS = 0x002e; // All Users\Documents - internal const int CSIDL_COMMON_MUSIC = 0x0035; // All Users\My Music - internal const int CSIDL_COMMON_OEM_LINKS = 0x003a; // Links to All Users OEM specific apps - internal const int CSIDL_COMMON_PICTURES = 0x0036; // All Users\My Pictures - internal const int CSIDL_COMMON_STARTMENU = 0x0016; // All Users\Start Menu - internal const int CSIDL_COMMON_PROGRAMS = 0X0017; // All Users\Start Menu\Programs - internal const int CSIDL_COMMON_STARTUP = 0x0018; // All Users\Startup - internal const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019; // All Users\Desktop - internal const int CSIDL_COMMON_TEMPLATES = 0x002d; // All Users\Templates - internal const int CSIDL_COMMON_VIDEO = 0x0037; // All Users\My Video - internal const int CSIDL_FONTS = 0x0014; // windows\fonts - internal const int CSIDL_MYVIDEO = 0x000e; // "My Videos" folder - internal const int CSIDL_NETHOOD = 0x0013; // %APPDATA%\Microsoft\Windows\Network Shortcuts - internal const int CSIDL_PRINTHOOD = 0x001b; // %APPDATA%\Microsoft\Windows\Printer Shortcuts - internal const int CSIDL_PROFILE = 0x0028; // %USERPROFILE% (%SystemDrive%\Users\%USERNAME%) - internal const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c; // x86 Program Files\Common on RISC - internal const int CSIDL_PROGRAM_FILESX86 = 0x002a; // x86 C:\Program Files on RISC - internal const int CSIDL_RESOURCES = 0x0038; // %windir%\Resources - internal const int CSIDL_RESOURCES_LOCALIZED = 0x0039; // %windir%\resources\0409 (code page) - internal const int CSIDL_SYSTEMX86 = 0x0029; // %windir%\system32 - internal const int CSIDL_WINDOWS = 0x0024; // GetWindowsDirectory() + internal const int CSIDL_FLAG_CREATE = 0x8000; // force folder creation in SHGetFolderPath + internal const int CSIDL_FLAG_DONT_VERIFY = 0x4000; // return an unverified folder path + internal const int CSIDL_ADMINTOOLS = 0x0030; // <user name>\Start Menu\Programs\Administrative Tools + internal const int CSIDL_CDBURN_AREA = 0x003b; // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning + internal const int CSIDL_COMMON_ADMINTOOLS = 0x002f; // All Users\Start Menu\Programs\Administrative Tools + internal const int CSIDL_COMMON_DOCUMENTS = 0x002e; // All Users\Documents + internal const int CSIDL_COMMON_MUSIC = 0x0035; // All Users\My Music + internal const int CSIDL_COMMON_OEM_LINKS = 0x003a; // Links to All Users OEM specific apps + internal const int CSIDL_COMMON_PICTURES = 0x0036; // All Users\My Pictures + internal const int CSIDL_COMMON_STARTMENU = 0x0016; // All Users\Start Menu + internal const int CSIDL_COMMON_PROGRAMS = 0X0017; // All Users\Start Menu\Programs + internal const int CSIDL_COMMON_STARTUP = 0x0018; // All Users\Startup + internal const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019; // All Users\Desktop + internal const int CSIDL_COMMON_TEMPLATES = 0x002d; // All Users\Templates + internal const int CSIDL_COMMON_VIDEO = 0x0037; // All Users\My Video + internal const int CSIDL_FONTS = 0x0014; // windows\fonts + internal const int CSIDL_MYVIDEO = 0x000e; // "My Videos" folder + internal const int CSIDL_NETHOOD = 0x0013; // %APPDATA%\Microsoft\Windows\Network Shortcuts + internal const int CSIDL_PRINTHOOD = 0x001b; // %APPDATA%\Microsoft\Windows\Printer Shortcuts + internal const int CSIDL_PROFILE = 0x0028; // %USERPROFILE% (%SystemDrive%\Users\%USERNAME%) + internal const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c; // x86 Program Files\Common on RISC + internal const int CSIDL_PROGRAM_FILESX86 = 0x002a; // x86 C:\Program Files on RISC + internal const int CSIDL_RESOURCES = 0x0038; // %windir%\Resources + internal const int CSIDL_RESOURCES_LOCALIZED = 0x0039; // %windir%\resources\0409 (code page) + internal const int CSIDL_SYSTEMX86 = 0x0029; // %windir%\system32 + internal const int CSIDL_WINDOWS = 0x0024; // GetWindowsDirectory() // .NET Framework 3.5 and earlier - all versions of windows - internal const int CSIDL_APPDATA = 0x001a; - internal const int CSIDL_COMMON_APPDATA = 0x0023; - internal const int CSIDL_LOCAL_APPDATA = 0x001c; - internal const int CSIDL_COOKIES = 0x0021; - internal const int CSIDL_FAVORITES = 0x0006; - internal const int CSIDL_HISTORY = 0x0022; - internal const int CSIDL_INTERNET_CACHE = 0x0020; - internal const int CSIDL_PROGRAMS = 0x0002; - internal const int CSIDL_RECENT = 0x0008; - internal const int CSIDL_SENDTO = 0x0009; - internal const int CSIDL_STARTMENU = 0x000b; - internal const int CSIDL_STARTUP = 0x0007; - internal const int CSIDL_SYSTEM = 0x0025; - internal const int CSIDL_TEMPLATES = 0x0015; - internal const int CSIDL_DESKTOPDIRECTORY = 0x0010; - internal const int CSIDL_PERSONAL = 0x0005; - internal const int CSIDL_PROGRAM_FILES = 0x0026; - internal const int CSIDL_PROGRAM_FILES_COMMON = 0x002b; - internal const int CSIDL_DESKTOP = 0x0000; - internal const int CSIDL_DRIVES = 0x0011; - internal const int CSIDL_MYMUSIC = 0x000d; - internal const int CSIDL_MYPICTURES = 0x0027; + internal const int CSIDL_APPDATA = 0x001a; + internal const int CSIDL_COMMON_APPDATA = 0x0023; + internal const int CSIDL_LOCAL_APPDATA = 0x001c; + internal const int CSIDL_COOKIES = 0x0021; + internal const int CSIDL_FAVORITES = 0x0006; + internal const int CSIDL_HISTORY = 0x0022; + internal const int CSIDL_INTERNET_CACHE = 0x0020; + internal const int CSIDL_PROGRAMS = 0x0002; + internal const int CSIDL_RECENT = 0x0008; + internal const int CSIDL_SENDTO = 0x0009; + internal const int CSIDL_STARTMENU = 0x000b; + internal const int CSIDL_STARTUP = 0x0007; + internal const int CSIDL_SYSTEM = 0x0025; + internal const int CSIDL_TEMPLATES = 0x0015; + internal const int CSIDL_DESKTOPDIRECTORY = 0x0010; + internal const int CSIDL_PERSONAL = 0x0005; + internal const int CSIDL_PROGRAM_FILES = 0x0026; + internal const int CSIDL_PROGRAM_FILES_COMMON = 0x002b; + internal const int CSIDL_DESKTOP = 0x0000; + internal const int CSIDL_DRIVES = 0x0011; + internal const int CSIDL_MYMUSIC = 0x000d; + internal const int CSIDL_MYPICTURES = 0x0027; internal const int NameSamCompatible = 2; - [DllImport(USER32, SetLastError=true, BestFitMapping=false)] + [DllImport(USER32, SetLastError = true, BestFitMapping = false)] internal static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, String lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult); [DllImport(KERNEL32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal extern static bool QueryUnbiasedInterruptTime(out ulong UnbiasedTime); -#if FEATURE_PAL - [DllImport(KERNEL32, EntryPoint = "PAL_Random")] - internal extern static bool Random(bool bStrong, - [Out, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, int length); -#else - private const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002; -#endif + internal const byte VER_GREATER_EQUAL = 0x3; + internal const uint VER_MAJORVERSION = 0x0000002; + internal const uint VER_MINORVERSION = 0x0000001; + internal const uint VER_SERVICEPACKMAJOR = 0x0000020; + internal const uint VER_SERVICEPACKMINOR = 0x0000010; + [DllImport("kernel32.dll")] + internal static extern bool VerifyVersionInfoW([In, Out] OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask); + [DllImport("kernel32.dll")] + internal static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask); } } |