summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Environment.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Environment.cs')
-rw-r--r--src/mscorlib/src/System/Environment.cs616
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);