diff options
Diffstat (limited to 'src/mscorlib/src/System/Environment.cs')
-rw-r--r-- | src/mscorlib/src/System/Environment.cs | 616 |
1 files changed, 97 insertions, 519 deletions
diff --git a/src/mscorlib/src/System/Environment.cs b/src/mscorlib/src/System/Environment.cs index 835219a01c..8fa4ce4ff5 100644 --- a/src/mscorlib/src/System/Environment.cs +++ b/src/mscorlib/src/System/Environment.cs @@ -18,7 +18,6 @@ namespace System { using System.Globalization; using System.Collections; using System.Collections.Generic; - using System.Security.Permissions; using System.Text; using System.Configuration.Assemblies; using System.Runtime.InteropServices; @@ -31,7 +30,6 @@ namespace System { using System.Runtime.Versioning; using System.Diagnostics.Contracts; - [ComVisible(true)] public enum EnvironmentVariableTarget { Process = 0, @@ -39,7 +37,6 @@ namespace System { Machine = 2, } - [ComVisible(true)] public static partial class Environment { // Assume the following constants include the terminating '\0' - use <, not <= @@ -72,23 +69,7 @@ namespace System { // Is this thread currently doing infinite resource lookups? private int infinitelyRecursingCount; - - // Data representing one individual resource lookup on a thread. - internal class GetResourceStringUserData - { - public ResourceHelper m_resourceHelper; - public String m_key; - public String m_retVal; - public bool m_lockWasTaken; - - public GetResourceStringUserData(ResourceHelper resourceHelper, String key) - { - m_resourceHelper = resourceHelper; - m_key = key; - } - } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal String GetResourceString(String key) { if (key == null || key.Length == 0) { Debug.Assert(false, "Environment::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?"); @@ -114,111 +95,85 @@ namespace System { // returning, we're going into an infinite loop and we should // return a bogus string. - GetResourceStringUserData userData = new GetResourceStringUserData(this, key); - - RuntimeHelpers.TryCode tryCode = new RuntimeHelpers.TryCode(GetResourceStringCode); - RuntimeHelpers.CleanupCode cleanupCode = new RuntimeHelpers.CleanupCode(GetResourceStringBackoutCode); - - RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(tryCode, cleanupCode, userData); - return userData.m_retVal; - } - - private void GetResourceStringCode(Object userDataIn) - { - GetResourceStringUserData userData = (GetResourceStringUserData) userDataIn; - ResourceHelper rh = userData.m_resourceHelper; - String key = userData.m_key; - - Monitor.Enter(rh, ref userData.m_lockWasTaken); - - // Are we recursively looking up the same resource? Note - our backout code will set - // the ResourceHelper's currentlyLoading stack to null if an exception occurs. - if (rh.currentlyLoading != null && rh.currentlyLoading.Count > 0 && rh.currentlyLoading.LastIndexOf(key) != -1) { - // We can start infinitely recursing for one resource lookup, - // then during our failure reporting, start infinitely recursing again. - // avoid that. - if (rh.infinitelyRecursingCount > 0) { - userData.m_retVal = "[Resource lookup failed - infinite recursion or critical failure detected.]"; - return; - } - rh.infinitelyRecursingCount++; + bool lockTaken = false; + try + { + Monitor.Enter(this, ref lockTaken); - // Note: our infrastructure for reporting this exception will again cause resource lookup. - // This is the most direct way of dealing with that problem. - String message = "Infinite recursion during resource lookup within "+System.CoreLib.Name+". This may be a bug in "+System.CoreLib.Name+", or potentially in certain extensibility points such as assembly resolve events or CultureInfo names. Resource name: " + key; - Assert.Fail("[Recursive resource lookup bug]", message, Assert.COR_E_FAILFAST, System.Diagnostics.StackTrace.TraceFormat.NoResourceLookup); - Environment.FailFast(message); - } - if (rh.currentlyLoading == null) - rh.currentlyLoading = new List<string>(); + // Are we recursively looking up the same resource? Note - our backout code will set + // the ResourceHelper's currentlyLoading stack to null if an exception occurs. + if (currentlyLoading != null && currentlyLoading.Count > 0 && currentlyLoading.LastIndexOf(key) != -1) + { + // We can start infinitely recursing for one resource lookup, + // then during our failure reporting, start infinitely recursing again. + // avoid that. + if (infinitelyRecursingCount > 0) + { + return "[Resource lookup failed - infinite recursion or critical failure detected.]"; + } + infinitelyRecursingCount++; - // Call class constructors preemptively, so that we cannot get into an infinite - // loop constructing a TypeInitializationException. If this were omitted, - // we could get the Infinite recursion assert above by failing type initialization - // between the Push and Pop calls below. - - if (!rh.resourceManagerInited) - { - // process-critical code here. No ThreadAbortExceptions - // can be thrown here. Other exceptions percolate as normal. - RuntimeHelpers.PrepareConstrainedRegions(); - try { + // Note: our infrastructure for reporting this exception will again cause resource lookup. + // This is the most direct way of dealing with that problem. + string message = $"Infinite recursion during resource lookup within {System.CoreLib.Name}. This may be a bug in {System.CoreLib.Name}, or potentially in certain extensibility points such as assembly resolve events or CultureInfo names. Resource name: {key}"; + Assert.Fail("[Recursive resource lookup bug]", message, Assert.COR_E_FAILFAST, System.Diagnostics.StackTrace.TraceFormat.NoResourceLookup); + Environment.FailFast(message); } - finally { + if (currentlyLoading == null) + currentlyLoading = new List<string>(); + + // Call class constructors preemptively, so that we cannot get into an infinite + // loop constructing a TypeInitializationException. If this were omitted, + // we could get the Infinite recursion assert above by failing type initialization + // between the Push and Pop calls below. + if (!resourceManagerInited) + { RuntimeHelpers.RunClassConstructor(typeof(ResourceManager).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(ResourceReader).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(RuntimeResourceSet).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(BinaryReader).TypeHandle); - rh.resourceManagerInited = true; + resourceManagerInited = true; } - - } - - rh.currentlyLoading.Add(key); // Push - - if (rh.SystemResMgr == null) { - rh.SystemResMgr = new ResourceManager(m_name, typeof(Object).Assembly); - } - String s = rh.SystemResMgr.GetString(key, null); - rh.currentlyLoading.RemoveAt(rh.currentlyLoading.Count - 1); // Pop - Debug.Assert(s!=null, "Managed resource string lookup failed. Was your resource name misspelled? Did you rebuild mscorlib after adding a resource to resources.txt? Debug this w/ cordbg and bug whoever owns the code that called Environment.GetResourceString. Resource name was: \""+key+"\""); + currentlyLoading.Add(key); // Push - userData.m_retVal = s; - } - - [PrePrepareMethod] - private void GetResourceStringBackoutCode(Object userDataIn, bool exceptionThrown) - { - GetResourceStringUserData userData = (GetResourceStringUserData) userDataIn; - ResourceHelper rh = userData.m_resourceHelper; + if (SystemResMgr == null) + { + SystemResMgr = new ResourceManager(m_name, typeof(Object).Assembly); + } + string s = SystemResMgr.GetString(key, null); + currentlyLoading.RemoveAt(currentlyLoading.Count - 1); // Pop - if (exceptionThrown) + Debug.Assert(s != null, "Managed resource string lookup failed. Was your resource name misspelled? Did you rebuild mscorlib after adding a resource to resources.txt? Debug this w/ cordbg and bug whoever owns the code that called Environment.GetResourceString. Resource name was: \"" + key + "\""); + return s; + } + catch { - if (userData.m_lockWasTaken) + if (lockTaken) { // Backout code - throw away potentially corrupt state - rh.SystemResMgr = null; - rh.currentlyLoading = null; + SystemResMgr = null; + currentlyLoading = null; } + throw; } - // Release the lock, if we took it. - if (userData.m_lockWasTaken) + finally { - Monitor.Exit(rh); + if (lockTaken) + { + Monitor.Exit(this); + } } } - } - private static volatile ResourceHelper m_resHelper; // Doesn't need to be initialized as they're zero-init. + private static volatile ResourceHelper m_resHelper; // Doesn't need to be initialized as they're zero-init. private const int MaxMachineNameLength = 256; // Private object for locking instead of locking on a public type for SQL reliability work. private static Object s_InternalSyncObject; private static Object InternalSyncObject { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] get { if (s_InternalSyncObject == null) { Object o = new Object(); @@ -266,9 +221,6 @@ namespace System { [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void FailFast(String message); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void FailFast(String message, uint exitCode); - // This overload of FailFast will allow you to specify the exception object // whose bucket details *could* be used when undergoing the failfast process. // To be specific: @@ -292,7 +244,7 @@ namespace System { **Arguments: The current directory to which to switch to the setter. **Exceptions: ==============================================================================*/ - public static String CurrentDirectory + internal static String CurrentDirectory { get{ return Directory.GetCurrentDirectory(); @@ -304,7 +256,7 @@ namespace System { } // Returns the system directory (ie, C:\WinNT\System32). - public static String SystemDirectory { + internal static String SystemDirectory { get { StringBuilder sb = new StringBuilder(Path.MaxPath); int r = Win32Native.GetSystemDirectory(sb, Path.MaxPath); @@ -316,20 +268,6 @@ namespace System { } } - // Returns the windows directory (ie, C:\WinNT). - // Used by NLS+ custom culures only at the moment. - internal static String InternalWindowsDirectory { - get { - StringBuilder sb = new StringBuilder(Path.MaxPath); - int r = Win32Native.GetWindowsDirectory(sb, Path.MaxPath); - Debug.Assert(r < Path.MaxPath, "r < Path.MaxPath"); - if (r==0) __Error.WinIOError(); - String path = sb.ToString(); - - return path; - } - } - public static String ExpandEnvironmentVariables(String name) { if (name == null) @@ -421,15 +359,6 @@ namespace System { } } - public static int SystemPageSize { - get { - (new EnvironmentPermission(PermissionState.Unrestricted)).Demand(); - Win32Native.SYSTEM_INFO info = new Win32Native.SYSTEM_INFO(); - Win32Native.GetSystemInfo(ref info); - return info.dwPageSize; - } - } - /*==============================GetCommandLineArgs============================== **Action: Gets the command line and splits it appropriately to deal with whitespace, ** quotes, and escape characters. @@ -439,7 +368,6 @@ namespace System { ==============================================================================*/ public static String[] GetCommandLineArgs() { - new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand(); /* * There are multiple entry points to a hosted app. * The host could use ::ExecuteAssembly() or ::CreateDelegate option @@ -515,38 +443,6 @@ namespace System { return block; } - /*===============================GetLogicalDrives=============================== - **Action: Retrieves the names of the logical drives on this machine in the form "C:\". - **Arguments: None. - **Exceptions: IOException. - **Permissions: SystemInfo Permission. - ==============================================================================*/ - public static String[] GetLogicalDrives() { - new EnvironmentPermission(PermissionState.Unrestricted).Demand(); - - int drives = Win32Native.GetLogicalDrives(); - if (drives==0) - __Error.WinIOError(); - uint d = (uint)drives; - int count = 0; - while (d != 0) { - if (((int)d & 1) != 0) count++; - d >>= 1; - } - String[] result = new String[count]; - char[] root = new char[] {'A', ':', '\\'}; - d = (uint)drives; - count = 0; - while (d != 0) { - if (((int)d & 1) != 0) { - result[count++] = new String(root); - } - d >>= 1; - root[0]++; - } - return result; - } - /*===================================NewLine==================================== **Action: A property which returns the appropriate newline string for the given ** platform. @@ -583,31 +479,13 @@ namespace System { } } - - /*==================================WorkingSet================================== - **Action: - **Returns: - **Arguments: - **Exceptions: - ==============================================================================*/ - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] - private static extern long GetWorkingSet(); - - public static long WorkingSet { - get { - new EnvironmentPermission(PermissionState.Unrestricted).Demand(); - return GetWorkingSet(); - } - } - - /*==================================OSVersion=================================== **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ - public static OperatingSystem OSVersion { + internal static OperatingSystem OSVersion { get { Contract.Ensures(Contract.Result<OperatingSystem>() != null); @@ -636,7 +514,6 @@ namespace System { } } -#if FEATURE_CORESYSTEM internal static bool IsWindows8OrAbove { get { @@ -652,47 +529,6 @@ namespace System { } #endif // FEATURE_COMINTEROP -#else // FEATURE_CORESYSTEM - - private static volatile bool s_IsWindows8OrAbove; - private static volatile bool s_CheckedOSWin8OrAbove; - - // Windows 8 version is 6.2 - internal static bool IsWindows8OrAbove { - get { - if (!s_CheckedOSWin8OrAbove) { - OperatingSystem OS = Environment.OSVersion; - s_IsWindows8OrAbove = (OS.Platform == PlatformID.Win32NT && - ((OS.Version.Major == 6 && OS.Version.Minor >= 2) || (OS.Version.Major > 6))); - s_CheckedOSWin8OrAbove = true; - } - return s_IsWindows8OrAbove; - } - } - -#if FEATURE_COMINTEROP - private static volatile bool s_WinRTSupported; - private static volatile bool s_CheckedWinRT; - - // Does the current version of Windows have Windows Runtime suppport? - internal static bool IsWinRTSupported { - get { - if (!s_CheckedWinRT) { - s_WinRTSupported = WinRTSupported(); - s_CheckedWinRT = true; - } - - return s_WinRTSupported; - } - } - - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - [SuppressUnmanagedCodeSecurity] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool WinRTSupported(); -#endif // FEATURE_COMINTEROP - -#endif // FEATURE_CORESYSTEM [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool GetVersion(Microsoft.Win32.Win32Native.OSVERSIONINFO osVer); @@ -711,7 +547,6 @@ namespace System { get { Contract.Ensures(Contract.Result<String>() != null); - new EnvironmentPermission(PermissionState.Unrestricted).Demand(); return GetStackTrace(null, true); } } @@ -806,16 +641,6 @@ namespace System { return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3 }); } - internal static string GetResourceString(string key, object val0, object val1, object val2, object val3, object val4) - { - return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3, val4 }); - } - - internal static string GetResourceString(string key, object val0, object val1, object val2, object val3, object val4, object val5) - { - return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3, val4, val5 }); - } - internal static String GetResourceString(string key, params object[] values) { return GetResourceStringFormatted(key, values); @@ -829,321 +654,74 @@ namespace System { return String.Format(CultureInfo.CurrentCulture, rs, values); } - // The following two internal methods are not used anywhere within the framework, - // but are being kept around as external platforms built on top of us have taken - // dependency by using private reflection on them for getting system resource strings - private static String GetRuntimeResourceString(String key) { - return GetResourceString(key); - } - - private static String GetRuntimeResourceString(String key, params Object[] values) { - return GetResourceStringFormatted(key,values); - } - - public static bool Is64BitProcess { - get { -#if BIT64 - return true; -#else // 32 - return false; -#endif - } - } - - public static bool Is64BitOperatingSystem { - get { -#if BIT64 - // 64-bit programs run only on 64-bit - return true; -#else // 32 - bool isWow64; // WinXP SP2+ and Win2k3 SP1+ - return Win32Native.DoesWin32MethodExist(Win32Native.KERNEL32, "IsWow64Process") - && Win32Native.IsWow64Process(Win32Native.GetCurrentProcess(), out isWow64) - && isWow64; -#endif - } - } - public static extern bool HasShutdownStarted { [MethodImplAttribute(MethodImplOptions.InternalCall)] get; } - public static string UserName { - get { - new EnvironmentPermission(EnvironmentPermissionAccess.Read,"UserName").Demand(); - - StringBuilder sb = new StringBuilder(256); - int size = sb.Capacity; - if (Win32Native.GetUserName(sb, ref size)) - { - return sb.ToString(); - } - return String.Empty; - } - } - - public static bool UserInteractive + internal static bool UserInteractive { get { return true; } } - - public static string GetFolderPath(SpecialFolder folder) { - if (!Enum.IsDefined(typeof(SpecialFolder), folder)) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)folder)); - Contract.EndContractBlock(); - - return InternalGetFolderPath(folder, SpecialFolderOption.None); - } - - public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option) { - if (!Enum.IsDefined(typeof(SpecialFolder),folder)) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)folder)); - if (!Enum.IsDefined(typeof(SpecialFolderOption),option)) - throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)option)); - Contract.EndContractBlock(); - - return InternalGetFolderPath(folder, option); + public static int CurrentManagedThreadId + { + get + { + return Thread.CurrentThread.ManagedThreadId; + } } - internal static string UnsafeGetFolderPath(SpecialFolder folder) + internal static extern int CurrentProcessorNumber { - return InternalGetFolderPath(folder, SpecialFolderOption.None, suppressSecurityChecks: true); + [MethodImplAttribute(MethodImplOptions.InternalCall)] + get; } - private static string InternalGetFolderPath(SpecialFolder folder, SpecialFolderOption option, bool suppressSecurityChecks = false) - { -#if FEATURE_CORESYSTEM - // This is currently customized for Windows Phone since CoreSystem doesn't support - // SHGetFolderPath. The allowed folder values are based on the version of .NET CF WP7 was using. - switch (folder) - { - case SpecialFolder.System: - return SystemDirectory; - case SpecialFolder.ApplicationData: - case SpecialFolder.Favorites: - case SpecialFolder.Programs: - case SpecialFolder.StartMenu: - case SpecialFolder.Startup: - case SpecialFolder.Personal: - throw new PlatformNotSupportedException(); - default: - throw new PlatformNotSupportedException(); - } -#else // FEATURE_CORESYSTEM - - StringBuilder sb = new StringBuilder(Path.MaxPath); - int hresult = Win32Native.SHGetFolderPath(IntPtr.Zero, /* hwndOwner: [in] Reserved */ - ((int)folder | (int)option), /* nFolder: [in] CSIDL */ - IntPtr.Zero, /* hToken: [in] access token */ - Win32Native.SHGFP_TYPE_CURRENT, /* dwFlags: [in] retrieve current path */ - sb); /* pszPath: [out]resultant path */ - String s; - if (hresult < 0) - { - switch (hresult) - { - default: - // The previous incarnation threw away all errors. In order to limit - // breaking changes, we will be permissive about these errors - // instead of calling ThowExceptionForHR. - //Runtime.InteropServices.Marshal.ThrowExceptionForHR(hresult); - break; - case __HResults.COR_E_PLATFORMNOTSUPPORTED: - // This one error is the one we do want to throw. + // The upper bits of t_executionIdCache are the executionId. The lower bits of + // the t_executionIdCache are counting down to get it periodically refreshed. + // TODO: Consider flushing the executionIdCache on Wait operations or similar + // actions that are likely to result in changing the executing core + [ThreadStatic] + static int t_executionIdCache; - throw new PlatformNotSupportedException(); - } + const int ExecutionIdCacheShift = 16; + const int ExecutionIdCacheCountDownMask = (1 << ExecutionIdCacheShift) - 1; + const int ExecutionIdRefreshRate = 5000; - // SHGetFolderPath does not initialize the output buffer on error - s = String.Empty; - } - else - { - s = sb.ToString(); - } + private static int RefreshExecutionId() + { + int executionId = CurrentProcessorNumber; - if (!suppressSecurityChecks) - { - // On CoreCLR we can check with the host if we're not trying to use any special options. - // Otherwise, we need to do a full demand since hosts aren't expecting to handle requests to - // create special folders. - if (option == SpecialFolderOption.None) - { - FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, s); - state.EnsureState(); - } - else - { - new FileIOPermission(FileIOPermissionAccess.PathDiscovery, s).Demand(); - } - } - return s; -#endif // FEATURE_CORESYSTEM - } + // On Unix, CurrentProcessorNumber is implemented in terms of sched_getcpu, which + // doesn't exist on all platforms. On those it doesn't exist on, GetCurrentProcessorNumber + // returns -1. As a fallback in that case and to spread the threads across the buckets + // by default, we use the current managed thread ID as a proxy. + if (executionId < 0) executionId = Environment.CurrentManagedThreadId; - public static string UserDomainName - { - get { - new EnvironmentPermission(EnvironmentPermissionAccess.Read,"UserDomain").Demand(); - - byte[] sid = new byte[1024]; - int sidLen = sid.Length; - StringBuilder domainName = new StringBuilder(1024); - uint domainNameLen = (uint) domainName.Capacity; - int peUse; - - byte ret = Win32Native.GetUserNameEx(Win32Native.NameSamCompatible, domainName, ref domainNameLen); - if (ret == 1) { - string samName = domainName.ToString(); - int index = samName.IndexOf('\\'); - if( index != -1) { - return samName.Substring(0, index); - } - } - domainNameLen = (uint) domainName.Capacity; - - bool success = Win32Native.LookupAccountName(null, UserName, sid, ref sidLen, domainName, ref domainNameLen, out peUse); - if (!success) { - int errorCode = Marshal.GetLastWin32Error(); - throw new InvalidOperationException(Win32Native.GetMessage(errorCode)); - } + Debug.Assert(ExecutionIdRefreshRate <= ExecutionIdCacheCountDownMask); - return domainName.ToString(); - } - } + // Mask with Int32.MaxValue to ensure the execution Id is not negative + t_executionIdCache = ((executionId << ExecutionIdCacheShift) & Int32.MaxValue) | ExecutionIdRefreshRate; - public enum SpecialFolderOption { - None = 0, - Create = Win32Native.CSIDL_FLAG_CREATE, - DoNotVerify = Win32Native.CSIDL_FLAG_DONT_VERIFY, - } - -//////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//////// -//////!!!!!! Keep the following locations synchronized !!!!!!//////// -//////!!!!!! 1) ndp\clr\src\BCL\Microsoft\Win32\Win32Native.cs !!!!!!//////// -//////!!!!!! 2) ndp\clr\src\BCL\System\Environment.cs !!!!!!//////// -//////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//////// - [ComVisible(true)] - public enum SpecialFolder { - // - // Represents the file system directory that serves as a common repository for - // application-specific data for the current, roaming user. - // A roaming user works on more than one computer on a network. A roaming user's - // profile is kept on a server on the network and is loaded onto a system when the - // user logs on. - // - ApplicationData = Win32Native.CSIDL_APPDATA, - // - // Represents the file system directory that serves as a common repository for application-specific data that - // is used by all users. - // - CommonApplicationData = Win32Native.CSIDL_COMMON_APPDATA, - // - // Represents the file system directory that serves as a common repository for application specific data that - // is used by the current, non-roaming user. - // - LocalApplicationData = Win32Native.CSIDL_LOCAL_APPDATA, - // - // Represents the file system directory that serves as a common repository for Internet - // cookies. - // - Cookies = Win32Native.CSIDL_COOKIES, - Desktop = Win32Native.CSIDL_DESKTOP, - // - // Represents the file system directory that serves as a common repository for the user's - // favorite items. - // - Favorites = Win32Native.CSIDL_FAVORITES, - // - // Represents the file system directory that serves as a common repository for Internet - // history items. - // - History = Win32Native.CSIDL_HISTORY, - // - // Represents the file system directory that serves as a common repository for temporary - // Internet files. - // - InternetCache = Win32Native.CSIDL_INTERNET_CACHE, - // - // Represents the file system directory that contains - // the user's program groups. - // - Programs = Win32Native.CSIDL_PROGRAMS, - MyComputer = Win32Native.CSIDL_DRIVES, - MyMusic = Win32Native.CSIDL_MYMUSIC, - MyPictures = Win32Native.CSIDL_MYPICTURES, - // "My Videos" folder - MyVideos = Win32Native.CSIDL_MYVIDEO, - // - // Represents the file system directory that contains the user's most recently used - // documents. - // - Recent = Win32Native.CSIDL_RECENT, - // - // Represents the file system directory that contains Send To menu items. - // - SendTo = Win32Native.CSIDL_SENDTO, - // - // Represents the file system directory that contains the Start menu items. - // - StartMenu = Win32Native.CSIDL_STARTMENU, - // - // Represents the file system directory that corresponds to the user's Startup program group. The system - // starts these programs whenever any user logs on to Windows NT, or - // starts Windows 95 or Windows 98. - // - Startup = Win32Native.CSIDL_STARTUP, - // - // System directory. - // - System = Win32Native.CSIDL_SYSTEM, - // - // Represents the file system directory that serves as a common repository for document - // templates. - // - Templates = Win32Native.CSIDL_TEMPLATES, - // - // Represents the file system directory used to physically store file objects on the desktop. - // This should not be confused with the desktop folder itself, which is - // a virtual folder. - // - DesktopDirectory = Win32Native.CSIDL_DESKTOPDIRECTORY, - // - // Represents the file system directory that serves as a common repository for documents. - // - Personal = Win32Native.CSIDL_PERSONAL, - // - // "MyDocuments" is a better name than "Personal" - // - MyDocuments = Win32Native.CSIDL_PERSONAL, - // - // Represents the program files folder. - // - ProgramFiles = Win32Native.CSIDL_PROGRAM_FILES, - // - // Represents the folder for components that are shared across applications. - // - CommonProgramFiles = Win32Native.CSIDL_PROGRAM_FILES_COMMON, + return executionId; } - public static int CurrentManagedThreadId + // Cached processor number used as a hint for which per-core stack to access. It is periodically + // refreshed to trail the actual thread core affinity. + internal static int CurrentExecutionId { - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return Thread.CurrentThread.ManagedThreadId; + int executionIdCache = t_executionIdCache--; + if ((executionIdCache & ExecutionIdCacheCountDownMask) == 0) + return RefreshExecutionId(); + return (executionIdCache >> ExecutionIdCacheShift); } } - internal static extern int CurrentProcessorNumber - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - get; - } - public static string GetEnvironmentVariable(string variable) { if (variable == null) @@ -1155,7 +733,7 @@ namespace System { return GetEnvironmentVariableCore(variable); } - public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) + internal static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) { if (variable == null) { @@ -1173,7 +751,7 @@ namespace System { return GetEnvironmentVariablesCore(); } - public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) + internal static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) { ValidateTarget(target); @@ -1188,7 +766,7 @@ namespace System { SetEnvironmentVariableCore(variable, value); } - public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) + internal static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) { ValidateVariableAndValue(variable, ref value); ValidateTarget(target); |