From 227c6546426c6dac34f5c546a64c589866250d68 Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Fri, 9 Dec 2016 20:36:32 -0800 Subject: [PATCH] Switch to use CoreLib Path class. (#13920) Leaving the code for UAP for now- we may end up needing to keep it. (Notably for the Crypto) Use the core environment variable code. --- .../System.Runtime.Extensions.sln | 62 ++++- .../src/System.Runtime.Extensions.csproj | 44 ++-- .../src/System/Environment.Uap.cs | 99 ++++++++ .../src/System/Environment.Unix.cs | 105 -------- .../src/System/Environment.Win32.Unix.cs | 42 ++++ .../src/System/Environment.Win32.cs | 233 +----------------- .../src/System/Environment.cs | 100 -------- 7 files changed, 224 insertions(+), 461 deletions(-) create mode 100644 src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs diff --git a/src/System.Runtime.Extensions/System.Runtime.Extensions.sln b/src/System.Runtime.Extensions/System.Runtime.Extensions.sln index 54d55b2bb662..a56140ab8633 100644 --- a/src/System.Runtime.Extensions/System.Runtime.Extensions.sln +++ b/src/System.Runtime.Extensions/System.Runtime.Extensions.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.Extensions", "src\System.Runtime.Extensions.csproj", "{845D2B72-D8A4-42E5-9BE9-17639EC4FC1A}" EndProject @@ -135,6 +135,66 @@ Global {9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU {9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU {9F312D76-9AF1-4E90-B3B0-815A1EC6C346}.Windows_Release|Any CPU.Build.0 = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Release|Any CPU.Build.0 = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Unix_Release|Any CPU.Build.0 = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU + {24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}.Windows_Release|Any CPU.Build.0 = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Release|Any CPU.Build.0 = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Unix_Release|Any CPU.Build.0 = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU + {AD83807C-8BE5-4F27-85DF-9793613233E1}.Windows_Release|Any CPU.Build.0 = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Debug|Any CPU.ActiveCfg = net46_Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Debug|Any CPU.Build.0 = net46_Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Release|Any CPU.ActiveCfg = net46_Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.net46_Release|Any CPU.Build.0 = net46_Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Debug|Any CPU.Build.0 = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Release|Any CPU.ActiveCfg = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.netstandard1.7_Release|Any CPU.Build.0 = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Release|Any CPU.Build.0 = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Debug|Any CPU.Build.0 = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Release|Any CPU.ActiveCfg = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Unix_Release|Any CPU.Build.0 = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU + {C44B33E3-F89F-40B9-B353-D380C1524988}.Windows_Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj b/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj index 418e4d5bef69..58d6d9b747af 100644 --- a/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj +++ b/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj @@ -55,13 +55,11 @@ - - @@ -140,8 +138,6 @@ - - Common\System\IO\Win32Marshal.cs @@ -160,15 +156,9 @@ Common\Interop\Windows\kernel32\Interop.GetCurrentDirectory.cs - - Common\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs - Common\Interop\Windows\kernel32\Interop.GetLongPathName.cs - - Common\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs - Common\Interop\Windows\kernel32\Interop.GetSystemInfo.cs @@ -196,20 +186,14 @@ Common\System\IO\PathInternal.Windows.cs - - Common\System\IO\PathInternal.Windows.StringBuffer.cs - + + + + - + - - - Common\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs - - - Common\Interop\Windows\BCrypt\Interop.NTSTATUS.cs - Common\Interop\Windows\kernel32\Interop.EnvironmentVariables.cs @@ -334,7 +318,6 @@ - Common\Interop\OSX\Interop.Libraries.cs @@ -420,12 +403,25 @@ + + + + + + + Common\System\IO\PathInternal.Windows.StringBuffer.cs + + + Common\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs + + + Common\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs + - @@ -472,4 +468,4 @@ - + \ No newline at end of file diff --git a/src/System.Runtime.Extensions/src/System/Environment.Uap.cs b/src/System.Runtime.Extensions/src/System/Environment.Uap.cs index 8acecaeb64c1..226ce363ca5e 100644 --- a/src/System.Runtime.Extensions/src/System/Environment.Uap.cs +++ b/src/System.Runtime.Extensions/src/System/Environment.Uap.cs @@ -58,5 +58,104 @@ private static void SetEnvironmentVariableCore(string variable, string value, En public static string UserName { get { throw new PlatformNotSupportedException(); } } public static string UserDomainName { get { throw new PlatformNotSupportedException(); } } + + + public static string GetEnvironmentVariable(string variable) + { + if (variable == null) + { + throw new ArgumentNullException(nameof(variable)); + } + + // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case + return GetEnvironmentVariableCore(variable); + } + + public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) + { + if (variable == null) + { + throw new ArgumentNullException(nameof(variable)); + } + + ValidateTarget(target); + + return GetEnvironmentVariableCore(variable, target); + } + + public static IDictionary GetEnvironmentVariables() + { + // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case + return GetEnvironmentVariablesCore(); + } + + public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) + { + ValidateTarget(target); + + return GetEnvironmentVariablesCore(target); + } + + public static void SetEnvironmentVariable(string variable, string value) + { + ValidateVariableAndValue(variable, ref value); + + // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case + SetEnvironmentVariableCore(variable, value); + } + + public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) + { + ValidateVariableAndValue(variable, ref value); + ValidateTarget(target); + + SetEnvironmentVariableCore(variable, value, target); + } + + private static void ValidateVariableAndValue(string variable, ref string value) + { + const int MaxEnvVariableValueLength = 32767; + + if (variable == null) + { + throw new ArgumentNullException(nameof(variable)); + } + if (variable.Length == 0) + { + throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable)); + } + if (variable[0] == '\0') + { + throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable)); + } + if (variable.Length >= MaxEnvVariableValueLength) + { + throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable)); + } + if (variable.IndexOf('=') != -1) + { + throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable)); + } + + if (string.IsNullOrEmpty(value) || value[0] == '\0') + { + // Explicitly null out value if it's empty + value = null; + } + else if (value.Length >= MaxEnvVariableValueLength) + { + throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value)); + } + } + + private static void ValidateTarget(EnvironmentVariableTarget target) + { + if (target != EnvironmentVariableTarget.Process && + target != EnvironmentVariableTarget.Machine && + target != EnvironmentVariableTarget.User) + { + throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target)); + } + } } } diff --git a/src/System.Runtime.Extensions/src/System/Environment.Unix.cs b/src/System.Runtime.Extensions/src/System/Environment.Unix.cs index 449d201f4ebf..3d01bfa839b5 100644 --- a/src/System.Runtime.Extensions/src/System/Environment.Unix.cs +++ b/src/System.Runtime.Extensions/src/System/Environment.Unix.cs @@ -16,28 +16,6 @@ namespace System { public static partial class Environment { - private static readonly unsafe Lazy> s_environ = new Lazy>(() => - { - var results = new LowLevelDictionary(); - byte** environ = Interop.Sys.GetEnviron(); - if (environ != null) - { - for (byte** ptr = environ; *ptr != null; ptr++) - { - string entry = Marshal.PtrToStringAnsi((IntPtr)(*ptr)); - int equalsPos = entry.IndexOf('='); - if (equalsPos != -1) - { - results.Add(entry.Substring(0, equalsPos), entry.Substring(equalsPos + 1)); - } - else - { - results.Add(entry, string.Empty); - } - } - } - return results; - }); internal static readonly bool IsMac = Interop.Sys.GetUnixName() == "OSX"; private static Func> s_fileReadLines; private static Action s_directoryCreateDirectory; @@ -76,45 +54,6 @@ private static string ExpandEnvironmentVariablesCore(string name) return StringBuilderCache.GetStringAndRelease(result); } - private static string GetEnvironmentVariableCore(string variable) - { - // Ensure variable doesn't include a null char - int nullEnd = variable.IndexOf('\0'); - if (nullEnd != -1) - { - variable = variable.Substring(0, nullEnd); - } - - // Get the value of the variable - lock (s_environ) - { - string value; - return s_environ.Value.TryGetValue(variable, out value) ? value : null; - } - } - - private static string GetEnvironmentVariableCore(string variable, EnvironmentVariableTarget target) - { - return target == EnvironmentVariableTarget.Process ? - GetEnvironmentVariableCore(variable) : - null; - } - - private static IDictionary GetEnvironmentVariablesCore() - { - lock (s_environ) - { - return s_environ.Value.Clone(); - } - } - - private static IDictionary GetEnvironmentVariablesCore(EnvironmentVariableTarget target) - { - return target == EnvironmentVariableTarget.Process ? - GetEnvironmentVariablesCore() : - new LowLevelDictionary(); - } - private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option) { // Get the path for the SpecialFolder @@ -419,50 +358,6 @@ private static int FindAndParseNextNumber(string text, ref int pos) public static int ProcessorCount => (int)Interop.Sys.SysConf(Interop.Sys.SysConfName._SC_NPROCESSORS_ONLN); - private static void SetEnvironmentVariableCore(string variable, string value) - { - int nullEnd; - - // Ensure variable doesn't include a null char - nullEnd = variable.IndexOf('\0'); - if (nullEnd != -1) - { - variable = variable.Substring(0, nullEnd); - } - - // Ensure value doesn't include a null char - if (value != null) - { - nullEnd = value.IndexOf('\0'); - if (nullEnd != -1) - { - value = value.Substring(0, nullEnd); - } - } - - lock (s_environ) - { - // Remove the entry if the value is null, otherwise add/overwrite it - if (value == null) - { - s_environ.Value.Remove(variable); - } - else - { - s_environ.Value[variable] = value; - } - } - } - - private static void SetEnvironmentVariableCore(string variable, string value, EnvironmentVariableTarget target) - { - if (target == EnvironmentVariableTarget.Process) - { - SetEnvironmentVariableCore(variable, value); - } - // other targets ignored - } - public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None); public static int SystemPageSize => (int)Interop.Sys.SysConf(Interop.Sys.SysConfName._SC_PAGESIZE); diff --git a/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs b/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs new file mode 100644 index 000000000000..272e370949cd --- /dev/null +++ b/src/System.Runtime.Extensions/src/System/Environment.Win32.Unix.cs @@ -0,0 +1,42 @@ +// 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. + +using Internal.Runtime.Augments; +using System.Collections; + +namespace System +{ + public static partial class Environment + { + public static string GetEnvironmentVariable(string variable) + { + return EnvironmentAugments.GetEnvironmentVariable(variable); + } + + public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) + { + return EnvironmentAugments.GetEnvironmentVariable(variable, target); + } + + public static IDictionary GetEnvironmentVariables() + { + return EnvironmentAugments.GetEnvironmentVariables(); + } + + public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) + { + return EnvironmentAugments.GetEnvironmentVariables(target); + } + + public static void SetEnvironmentVariable(string variable, string value) + { + EnvironmentAugments.SetEnvironmentVariable(variable, value); + } + + public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) + { + EnvironmentAugments.SetEnvironmentVariable(variable, value, target); + } + } +} diff --git a/src/System.Runtime.Extensions/src/System/Environment.Win32.cs b/src/System.Runtime.Extensions/src/System/Environment.Win32.cs index b653a7cb415f..ffdf5218d494 100644 --- a/src/System.Runtime.Extensions/src/System/Environment.Win32.cs +++ b/src/System.Runtime.Extensions/src/System/Environment.Win32.cs @@ -47,165 +47,6 @@ private static string ExpandEnvironmentVariablesCore(string name) return StringBuilderCache.GetStringAndRelease(result); } - private static string GetEnvironmentVariableCore(string variable) - { - StringBuilder sb = StringBuilderCache.Acquire(128); // a somewhat reasonable default size - int requiredSize = Interop.Kernel32.GetEnvironmentVariableW(variable, sb, sb.Capacity); - if (requiredSize == 0 && Marshal.GetLastWin32Error() == Interop.Errors.ERROR_ENVVAR_NOT_FOUND) - { - StringBuilderCache.Release(sb); - return null; - } - - while (requiredSize > sb.Capacity) - { - sb.Capacity = requiredSize; - sb.Length = 0; - requiredSize = Interop.Kernel32.GetEnvironmentVariableW(variable, sb, sb.Capacity); - } - - return StringBuilderCache.GetStringAndRelease(sb); - } - - private static string GetEnvironmentVariableCore(string variable, EnvironmentVariableTarget target) - { - if (target == EnvironmentVariableTarget.Process) - { - return GetEnvironmentVariableCore(variable); - } - else - { - RegistryKey baseKey; - string keyName; - - if (target == EnvironmentVariableTarget.Machine) - { - baseKey = Registry.LocalMachine; - keyName = @"System\CurrentControlSet\Control\Session Manager\Environment"; - } - else - { - Debug.Assert(target == EnvironmentVariableTarget.User); - baseKey = Registry.CurrentUser; - keyName = "Environment"; - } - - using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false)) - { - return environmentKey?.GetValue(variable) as string; - } - } - } - - private static IDictionary GetEnvironmentVariablesCore() - { - // Format for GetEnvironmentStrings is: - // (=HiddenVar=value\0 | Variable=value\0)* \0 - // See the description of Environment Blocks in MSDN's - // CreateProcess page (null-terminated array of null-terminated strings). - // Note the =HiddenVar's aren't always at the beginning. - - // Copy strings out, parsing into pairs and inserting into the table. - // The first few environment variable entries start with an '='. - // The current working directory of every drive (except for those drives - // you haven't cd'ed into in your DOS window) are stored in the - // environment block (as =C:=pwd) and the program's exit code is - // as well (=ExitCode=00000000). - - var results = new LowLevelDictionary(); - char[] block = GetEnvironmentCharArray(); - for (int i = 0; i < block.Length; i++) - { - int startKey = i; - - // Skip to key. On some old OS, the environment block can be corrupted. - // Some will not have '=', so we need to check for '\0'. - while (block[i] != '=' && block[i] != '\0') i++; - if (block[i] == '\0') continue; - - // Skip over environment variables starting with '=' - if (i - startKey == 0) - { - while (block[i] != 0) i++; - continue; - } - - string key = new string(block, startKey, i - startKey); - i++; // skip over '=' - - int startValue = i; - while (block[i] != 0) i++; // Read to end of this entry - string value = new string(block, startValue, i - startValue); // skip over 0 handled by for loop's i++ - - results[key] = value; - } - return results; - } - - private static IDictionary GetEnvironmentVariablesCore(EnvironmentVariableTarget target) - { - if (target == EnvironmentVariableTarget.Process) - { - return GetEnvironmentVariablesCore(); - } - else - { - RegistryKey baseKey; - string keyName; - if (target == EnvironmentVariableTarget.Machine) - { - baseKey = Registry.LocalMachine; - keyName = @"System\CurrentControlSet\Control\Session Manager\Environment"; - } - else - { - Debug.Assert(target == EnvironmentVariableTarget.User); - baseKey = Registry.CurrentUser; - keyName = @"Environment"; - } - - using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false)) - { - var table = new LowLevelDictionary(); - if (environmentKey != null) - { - foreach (string name in environmentKey.GetValueNames()) - { - table.Add(name, environmentKey.GetValue(name, "").ToString()); - } - } - return table; - } - } - } - - private static unsafe char[] GetEnvironmentCharArray() - { - // Format for GetEnvironmentStrings is: - // [=HiddenVar=value\0]* [Variable=value\0]* \0 - // See the description of Environment Blocks in MSDN's - // CreateProcess page (null-terminated array of null-terminated strings). - char* pStrings = Interop.Kernel32.GetEnvironmentStringsW(); - if (pStrings == null) - { - throw new OutOfMemoryException(); - } - try - { - // Search for terminating \0\0 (two unicode \0's). - char* p = pStrings; - while (!(*p == '\0' && *(p + 1) == '\0')) p++; - - var block = new char[(int)(p - pStrings + 1)]; - Marshal.Copy((IntPtr)pStrings, block, 0, block.Length); - return block; - } - finally - { - Interop.Kernel32.FreeEnvironmentStringsW(pStrings); // ignore any cleanup error - } - } - private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option) { // We're using SHGetKnownFolderPath instead of SHGetFolderPath as SHGetFolderPath is @@ -478,82 +319,12 @@ public static int ProcessorCount return 0; }); - private static void SetEnvironmentVariableCore(string variable, string value) - { - if (!Interop.Kernel32.SetEnvironmentVariableW(variable, value)) - { - int errorCode = Marshal.GetLastWin32Error(); - switch (errorCode) - { - case Interop.Errors.ERROR_ENVVAR_NOT_FOUND: // Allow user to try to clear a environment variable - return; - case Interop.Errors.ERROR_FILENAME_EXCED_RANGE: // Fix inaccurate error code from Win32 - throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value)); - default: - throw new ArgumentException(Interop.Kernel32.GetMessage(errorCode)); - } - } - } - - private static void SetEnvironmentVariableCore(string variable, string value, EnvironmentVariableTarget target) - { - if (target == EnvironmentVariableTarget.Process) - { - SetEnvironmentVariableCore(variable, value); - } - else - { - RegistryKey baseKey; - string keyName; - - if (target == EnvironmentVariableTarget.Machine) - { - baseKey = Registry.LocalMachine; - keyName = @"System\CurrentControlSet\Control\Session Manager\Environment"; - } - else - { - Debug.Assert(target == EnvironmentVariableTarget.User); - - // User-wide environment variables stored in the registry are limited to 255 chars for the environment variable name. - const int MaxUserEnvVariableLength = 255; - if (variable.Length >= MaxUserEnvVariableLength) - { - throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable)); - } - - baseKey = Registry.CurrentUser; - keyName = "Environment"; - } - - using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: true)) - { - if (environmentKey != null) - { - if (value == null) - { - environmentKey.DeleteValue(variable, throwOnMissingValue: false); - } - else - { - environmentKey.SetValue(variable, value); - } - } - } - } - - //// Desktop sends a WM_SETTINGCHANGE message to all windows. Not available on all platforms. - //Interop.Kernel32.SendMessageTimeout( - // new IntPtr(Interop.Kernel32.HWND_BROADCAST), Interop.Kernel32.WM_SETTINGCHANGE, - // IntPtr.Zero, "Environment", 0, 1000, IntPtr.Zero); - } - public static string SystemDirectory { get { - StringBuilder sb = StringBuilderCache.Acquire(Path.MaxPath); - if (Interop.Kernel32.GetSystemDirectoryW(sb, Path.MaxPath) == 0) + StringBuilder sb = StringBuilderCache.Acquire(PathInternal.MaxShortPath); + if (Interop.Kernel32.GetSystemDirectoryW(sb, PathInternal.MaxShortPath) == 0) { StringBuilderCache.Release(sb); throw Win32Marshal.GetExceptionForLastWin32Error(); diff --git a/src/System.Runtime.Extensions/src/System/Environment.cs b/src/System.Runtime.Extensions/src/System/Environment.cs index 97bea9c5f847..2ee6efc7da9e 100644 --- a/src/System.Runtime.Extensions/src/System/Environment.cs +++ b/src/System.Runtime.Extensions/src/System/Environment.cs @@ -3,8 +3,6 @@ // See the LICENSE file in the project root for more information. using Internal.Runtime.Augments; -using System; -using System.Collections; using System.IO; using System.Reflection; using System.Text; @@ -93,42 +91,6 @@ public static string ExpandEnvironmentVariables(string name) public static string[] GetCommandLineArgs() => EnvironmentAugments.GetCommandLineArgs(); - public static string GetEnvironmentVariable(string variable) - { - if (variable == null) - { - throw new ArgumentNullException(nameof(variable)); - } - - // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case - return GetEnvironmentVariableCore(variable); - } - - public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) - { - if (variable == null) - { - throw new ArgumentNullException(nameof(variable)); - } - - ValidateTarget(target); - - return GetEnvironmentVariableCore(variable, target); - } - - public static IDictionary GetEnvironmentVariables() - { - // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case - return GetEnvironmentVariablesCore(); - } - - public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) - { - ValidateTarget(target); - - return GetEnvironmentVariablesCore(target); - } - public static string GetFolderPath(SpecialFolder folder) => GetFolderPath(folder, SpecialFolderOption.None); public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option) @@ -151,58 +113,6 @@ public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption opt public static bool Is64BitProcess => IntPtr.Size == 8; public static bool Is64BitOperatingSystem => Is64BitProcess || Is64BitOperatingSystemWhen32BitProcess; - - public static void SetEnvironmentVariable(string variable, string value) - { - ValidateVariableAndValue(variable, ref value); - - // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case - SetEnvironmentVariableCore(variable, value); - } - - public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) - { - ValidateVariableAndValue(variable, ref value); - ValidateTarget(target); - - SetEnvironmentVariableCore(variable, value, target); - } - - private static void ValidateVariableAndValue(string variable, ref string value) - { - const int MaxEnvVariableValueLength = 32767; - - if (variable == null) - { - throw new ArgumentNullException(nameof(variable)); - } - if (variable.Length == 0) - { - throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable)); - } - if (variable[0] == '\0') - { - throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable)); - } - if (variable.Length >= MaxEnvVariableValueLength) - { - throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable)); - } - if (variable.IndexOf('=') != -1) - { - throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable)); - } - - if (string.IsNullOrEmpty(value) || value[0] == '\0') - { - // Explicitly null out value if it's empty - value = null; - } - else if (value.Length >= MaxEnvVariableValueLength) - { - throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value)); - } - } public static OperatingSystem OSVersion => s_osVersion.Value; @@ -244,15 +154,5 @@ public static long WorkingSet return 0; } } - - private static void ValidateTarget(EnvironmentVariableTarget target) - { - if (target != EnvironmentVariableTarget.Process && - target != EnvironmentVariableTarget.Machine && - target != EnvironmentVariableTarget.User) - { - throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target)); - } - } } }