Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Environment.cs / 2 / Environment.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: Environment ** ** ** Purpose: Provides some basic access to some environment ** functionality. ** ** ============================================================*/ namespace System { using System.IO; using System.Security; using System.Resources; using System.Globalization; using System.Collections; using System.Security.Permissions; using System.Text; using System.Configuration.Assemblies; using System.Runtime.InteropServices; using System.Reflection; using System.Diagnostics; using Microsoft.Win32; using System.Runtime.CompilerServices; using System.Threading; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; #if !FEATURE_PAL [ComVisible(true)] public enum EnvironmentVariableTarget { Process = 0, User = 1, Machine = 2, } #endif [ComVisible(true)] public static class Environment { const int MaximumLength = 32767; // maximun length for environment vairable name and value internal sealed class ResourceHelper { private ResourceManager SystemResMgr; // To avoid infinite loops when calling GetResourceString. See comments // in GetResourceString for this field. private Stack currentlyLoading; // process-wide state (since this is only used in one domain), // used to avoid the TypeInitialization infinite recusion // in GetResourceStringCode internal bool resourceManagerInited = false; 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) { BCLDebug.Assert(false, "Environment::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?"); return "[Resource lookup failed - null or empty resource name]"; } // We have a somewhat common potential for infinite // loops with mscorlib's ResourceManager. If "potentially dangerous" // code throws an exception, we will get into an infinite loop // inside the ResourceManager and this "potentially dangerous" code. // Potentially dangerous code includes the IO package, CultureInfo, // parts of the loader, some parts of Reflection, Security (including // custom user-written permissions that may parse an XML file at // class load time), assembly load event handlers, etc. Essentially, // this is not a bounded set of code, and we need to fix the problem. // Fortunately, this is limited to mscorlib's error lookups and is NOT // a general problem for all user code using the ResourceManager. // The solution is to make sure only one thread at a time can call // GetResourceString. Also, since resource lookups can be // reentrant, if the same thread comes into GetResourceString // twice looking for the exact same resource name before // 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.ReliableEnter(rh, ref userData.m_lockWasTaken); // Are we recursively looking up the same resource? if (rh.currentlyLoading != null && rh.currentlyLoading.Count > 0 && rh.currentlyLoading.Contains(key)) { // This is often a bug in the BCL, security, NLS+ code, // or the loader somewhere. However, this could also // be a setup problem - check whether mscorlib & // mscorwks are both of the same build flavor. String stackTrace = "[Couldn't get a stack trace]"; try { StackTrace st = new StackTrace(true); // Don't attempt to localize strings in this stack trace, otherwise it could cause // infinite recursion. This stack trace is used for an Assert message only, and // so the lack of localization should not be an issue. stackTrace = st.ToString( System.Diagnostics.StackTrace.TraceFormat.NoResourceLookup ); } catch(StackOverflowException) {} catch(NullReferenceException) {} catch(OutOfMemoryException) {} BCLDebug.Assert(false, "Infinite recursion during resource lookup. Resource name: "+key+"\r\n"+stackTrace); // Note: can't append the key name, since that may require // an extra allocation... userData.m_retVal = "[Resource lookup failed - infinite recursion or critical failure detected.]"; return; } if (rh.currentlyLoading == null) rh.currentlyLoading = new Stack(4); // 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 { } finally { RuntimeHelpers.RunClassConstructor(typeof(ResourceManager).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(ResourceReader).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(RuntimeResourceSet).TypeHandle); RuntimeHelpers.RunClassConstructor(typeof(BinaryReader).TypeHandle); rh.resourceManagerInited = true; } } rh.currentlyLoading.Push(key); if (rh.SystemResMgr == null) rh.SystemResMgr = new ResourceManager("mscorlib", typeof(Object).Assembly); String s = rh.SystemResMgr.GetString(key, null); rh.currentlyLoading.Pop(); BCLDebug.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 rhironment.GetResourceString. Resource name was: \""+key+"\""); userData.m_retVal = s; } [PrePrepareMethod] private void GetResourceStringBackoutCode(Object userDataIn, bool exceptionThrown) { GetResourceStringUserData userData = (GetResourceStringUserData) userDataIn; ResourceHelper rh = userData.m_resourceHelper; if (exceptionThrown) { if (userData.m_lockWasTaken) { // Backout code - throw away potentially corrupt state rh.SystemResMgr = null; rh.currentlyLoading = null; } } // Release the lock, if we took it. if (userData.m_lockWasTaken) { Monitor.Exit(rh); } } } private static ResourceHelper m_resHelper; // Doesn't need to be initialized as they're zero-init. #if IO_CANCELLATION_ENABLED private static bool s_IsLonghorn; private static bool s_CheckedOSType; #endif private static bool s_IsW2k3; private static volatile bool s_CheckedOSW2k3; 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(); Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); } return s_InternalSyncObject; } } #if !FEATURE_PAL private static OperatingSystem m_os; // Cached OperatingSystem value private static OSName m_osname; #endif // !FEATURE_PAL /*==================================TickCount=================================== **Action: Gets the number of ticks since the system was started. **Returns: The number of ticks since the system was started. **Arguments: None **Exceptions: None ==============================================================================*/ public static int TickCount { get { return nativeGetTickCount(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int nativeGetTickCount(); // Terminates this process with the given exit code. [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void ExitNative(int exitCode); [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] public static void Exit(int exitCode) { ExitNative(exitCode); } public static int ExitCode { get { return nativeGetExitCode(); } set { nativeSetExitCode(value); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void nativeSetExitCode(int exitCode); // Gets the exit code of the process. [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int nativeGetExitCode(); [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void FailFast(String message); public static String CommandLine { get { new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand(); return GetCommandLineNative(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern String GetCommandLineNative(); /*===============================CurrentDirectory=============================== **Action: Provides a getter and setter for the current directory. The original ** current directory is the one from which the process was started. **Returns: The current directory (from the getter). Void from the setter. **Arguments: The current directory to which to switch to the setter. **Exceptions: ==============================================================================*/ public static String CurrentDirectory { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] get{ return Directory.GetCurrentDirectory(); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] set { Directory.SetCurrentDirectory(value); } } // Returns the system directory (ie, C:\WinNT\System32). public static String SystemDirectory { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] get { StringBuilder sb = new StringBuilder(Path.MAX_PATH); int r = Win32Native.GetSystemDirectory(sb, Path.MAX_PATH); BCLDebug.Assert(r < Path.MAX_PATH, "r < Path.MAX_PATH"); if (r==0) __Error.WinIOError(); String path = sb.ToString(); // Do security check new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand(); return path; } } #if !FEATURE_PAL // Returns the windows directory (ie, C:\WinNT). // Used by NLS+ custom culures only at the moment. internal static String InternalWindowsDirectory { [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] get { StringBuilder sb = new StringBuilder(Path.MAX_PATH); int r = Win32Native.GetWindowsDirectory(sb, Path.MAX_PATH); BCLDebug.Assert(r < Path.MAX_PATH, "r < Path.MAX_PATH"); if (r==0) __Error.WinIOError(); String path = sb.ToString(); return path; } } public static String ExpandEnvironmentVariables(String name) { if (name == null) throw new ArgumentNullException("name"); if (name.Length == 0) { return name; } // Do a security check to guarantee we can read each of the // individual environment variables requested here. String[] varArray = name.Split(new char[] {'%'}); StringBuilder vars = new StringBuilder(); int currentSize = 100; StringBuilder blob = new StringBuilder(currentSize); // A somewhat reasonable default size int size; for(int i=1; icurrentSize) { currentSize = size; blob.Capacity = currentSize; blob.Length = 0; size = Win32Native.ExpandEnvironmentStrings(envVar, blob, currentSize); if (size == 0) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } String temp = blob.ToString(); if (temp != envVar) { // We expanded successfully, we need to do String comparision here // since %FOO% can become %FOOD vars.Append(varArray[i]); vars.Append(';'); } } new EnvironmentPermission(EnvironmentPermissionAccess.Read, vars.ToString()).Demand(); blob.Length = 0; size = Win32Native.ExpandEnvironmentStrings(name, blob, currentSize); if (size == 0) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); while (size > currentSize) { currentSize = size; blob.Capacity = currentSize; blob.Length = 0; size = Win32Native.ExpandEnvironmentStrings(name, blob, currentSize); if (size == 0) Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } return blob.ToString(); } #endif // FEATURE_PAL public static String MachineName { get { // In future release of operating systems, you might be able to rename a machine without // rebooting. Therefore, don't cache this machine name. new EnvironmentPermission(EnvironmentPermissionAccess.Read, "COMPUTERNAME").Demand(); StringBuilder buf = new StringBuilder(MaxMachineNameLength); int len = MaxMachineNameLength; if (Win32Native.GetComputerName(buf, ref len) == 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ComputerName")); return buf.ToString(); } } public static int ProcessorCount { get { new EnvironmentPermission(EnvironmentPermissionAccess.Read, "NUMBER_OF_PROCESSORS").Demand(); Win32Native.SYSTEM_INFO info = new Win32Native.SYSTEM_INFO(); Win32Native.GetSystemInfo( ref info ); return info.dwNumberOfProcessors; } } /*==============================GetCommandLineArgs============================== **Action: Gets the command line and splits it appropriately to deal with whitespace, ** quotes, and escape characters. **Returns: A string array containing your command line arguments. **Arguments: None **Exceptions: None. ==============================================================================*/ public static String[] GetCommandLineArgs() { new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand(); return GetCommandLineArgsNative(); } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern String[] GetCommandLineArgsNative(); // We need to keep this Fcall since it is used in AppDomain.cs. // If we call GetEnvironmentVariable from AppDomain.cs, we will use StringBuilder class. // That has side effect to change the ApartmentState of the calling Thread to MTA. // So runtime can't change the ApartmentState of calling thread any more. [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern String nativeGetEnvironmentVariable(String variable); /*============================GetEnvironmentVariable============================ **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static String GetEnvironmentVariable(String variable) { if (variable == null) throw new ArgumentNullException("variable"); (new EnvironmentPermission(EnvironmentPermissionAccess.Read, variable)).Demand(); StringBuilder blob = new StringBuilder(128); // A somewhat reasonable default size int requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity); if( requiredSize == 0) { // GetEnvironmentVariable failed if( Marshal.GetLastWin32Error() == Win32Native.ERROR_ENVVAR_NOT_FOUND) return null; } while (requiredSize > blob.Capacity) { // need to retry since the environment variable might be changed blob.Capacity = requiredSize; blob.Length = 0; requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity); } return blob.ToString(); } #if !FEATURE_PAL [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static string GetEnvironmentVariable( string variable, EnvironmentVariableTarget target) { if( target == EnvironmentVariableTarget.Process) { return GetEnvironmentVariable(variable); } if (variable == null) { throw new ArgumentNullException("variable"); } // Win9x doesn't support machine or user level environment variables if( IsWin9X() ){ throw new NotSupportedException(Environment.GetResourceString("PlatformNotSupported_Win9x")); } (new EnvironmentPermission(PermissionState.Unrestricted)).Demand(); if( target == EnvironmentVariableTarget.Machine) { using (RegistryKey environmentKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment", false)) { string value = environmentKey.GetValue(variable) as string; return value; } } else if( target == EnvironmentVariableTarget.User) { using (RegistryKey environmentKey = Registry.CurrentUser.OpenSubKey("Environment", false)) { string value = environmentKey.GetValue(variable) as string; return value; } } else { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_EnumIllegalVal"), (int)target)); } } #endif /*===========================GetEnvironmentVariables============================ **Action: Returns an IDictionary containing all enviroment variables and their values. **Returns: An IDictionary containing all environment variables and their values. **Arguments: None. **Exceptions: None. ==============================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] [ResourceExposure(ResourceScope.Machine)] private static extern char[] nativeGetEnvironmentCharArray(); [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static IDictionary GetEnvironmentVariables() { // Using an FCall is better than using PInvoke here since // Interop Marshaler can't handle string which contains '\0', we need // to allocate an unmanaged buffer, do the conversion and free the buffer // if we do use PInvoke. char[] block = nativeGetEnvironmentCharArray(); if( block == null) { throw new OutOfMemoryException(); } Hashtable table = new Hashtable(20); StringBuilder vars = new StringBuilder(); // 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) Skip all that start with =. // Read docs about Environment Blocks on MSDN's CreateProcess page. // 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. // GetEnvironmentCharArray will not return the trailing 0 to terminate // the array - we have the array length instead. bool first = true; for(int i=0; i = MaximumLength) { throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue")); } } if(!Win32Native.SetEnvironmentVariable(variable, value)) { int errorCode = Marshal.GetLastWin32Error(); // Allow user to try to clear a environment variable if( errorCode == Win32Native.ERROR_ENVVAR_NOT_FOUND) { return; } // The error message from Win32 is "The filename or extension is too long", // which is not accurate. if( errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) { throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue")); } throw new ArgumentException(Win32Native.GetMessage(errorCode)); } } private static void CheckEnvironmentVariableName(string variable) { if (variable == null) { throw new ArgumentNullException("variable"); } if( variable.Length == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_StringZeroLength"), "variable"); } if( variable[0] == '\0') { throw new ArgumentException(Environment.GetResourceString("Argument_StringFirstCharIsZero"), "variable"); } if( variable.Length >= MaximumLength ) { throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue")); } if( variable.IndexOf('=') != -1) { throw new ArgumentException(Environment.GetResourceString("Argument_IllegalEnvVarName")); } } #if !FEATURE_PAL [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) { if( target == EnvironmentVariableTarget.Process) { SetEnvironmentVariable(variable, value); return; } CheckEnvironmentVariableName(variable); const int MaxKeyLength = 255; // maximum registry key length // Win9X doesn't support registry name with more than 255 characters if( variable.Length >= MaxKeyLength) { throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarName")); } // Win9x doesn't support machine or user level environment variables if( IsWin9X() ){ throw new NotSupportedException(Environment.GetResourceString("PlatformNotSupported_Win9x")); } new EnvironmentPermission(PermissionState.Unrestricted).Demand(); // explicitly null out value if is the empty string. if (String.IsNullOrEmpty(value) || value[0] == '\0') { value = null; } if( target == EnvironmentVariableTarget.Machine) { using (RegistryKey environmentKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment", true)) { if (value == null) environmentKey.DeleteValue(variable, false); else environmentKey.SetValue(variable, value); } } else if( target == EnvironmentVariableTarget.User) { using (RegistryKey environmentKey = Registry.CurrentUser.OpenSubKey("Environment", true)) { if (value == null) environmentKey.DeleteValue(variable, false); else environmentKey.SetValue(variable, value); } } else { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_EnumIllegalVal"), (int)target)); } // send a WM_SETTINGCHANGE message to all windows IntPtr r = Win32Native.SendMessageTimeout(new IntPtr(Win32Native.HWND_BROADCAST), Win32Native.WM_SETTINGCHANGE, IntPtr.Zero, "Environment", 0, 1000, IntPtr.Zero); if (r == IntPtr.Zero) BCLDebug.Assert(false, "SetEnvironmentVariable failed: " + Marshal.GetLastWin32Error()); } #endif /*===============================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() { #if !PLATFORM_UNIX 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; #else return new String[0]; #endif // !PLATFORM_UNIX } /*===================================NewLine==================================== **Action: A property which returns the appropriate newline string for the given ** platform. **Returns: \r\n on Win32. **Arguments: None. **Exceptions: None. ==============================================================================*/ public static String NewLine { get { #if !PLATFORM_UNIX return "\r\n"; #else return "\n"; #endif // !PLATFORM_UNIX } } /*===================================Version==================================== **Action: Returns the COM+ version struct, describing the build number. **Returns: **Arguments: **Exceptions: ==============================================================================*/ public static Version Version { get { return new Version(ThisAssembly.InformationalVersion); } } /*==================================WorkingSet================================== **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern long nativeGetWorkingSet(); public static long WorkingSet { get { new EnvironmentPermission(PermissionState.Unrestricted).Demand(); return (long)nativeGetWorkingSet(); } } #if !FEATURE_PAL /*==================================OSVersion=================================== **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ public static OperatingSystem OSVersion { get { if (m_os==null) { // We avoid the lock since we don't care if two threads will set this at the same time. Microsoft.Win32.Win32Native.OSVERSIONINFO osvi = new Microsoft.Win32.Win32Native.OSVERSIONINFO(); if (!Win32Native.GetVersionEx(osvi)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GetVersion")); } Microsoft.Win32.Win32Native.OSVERSIONINFOEX osviEx = new Microsoft.Win32.Win32Native.OSVERSIONINFOEX(); if( osvi.PlatformId != Win32Native.VER_PLATFORM_WIN32_WINDOWS) { // for OS other than win9x, we need to get Service pack information if (!Win32Native.GetVersionEx(osviEx)) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GetVersion")); } } PlatformID id; switch (osvi.PlatformId) { case Win32Native.VER_PLATFORM_WIN32_NT: id = PlatformID.Win32NT; break; case Win32Native.VER_PLATFORM_WIN32_WINDOWS: id = PlatformID.Win32Windows; break; case Win32Native.VER_PLATFORM_WIN32s: id = PlatformID.Win32S; break; case Win32Native.VER_PLATFORM_WINCE: id = PlatformID.WinCE; break; default: BCLDebug.Assert(false,"false"); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_InvalidPlatformID")); } Version v = new Version(osvi.MajorVersion, osvi.MinorVersion, osvi.BuildNumber, (osviEx.ServicePackMajor << 16) |osviEx.ServicePackMinor); m_os = new OperatingSystem(id, v, osvi.CSDVersion); } BCLDebug.Assert(m_os != null, "m_os != null"); return m_os; } } #if IO_CANCELLATION_ENABLED internal static bool IsLonghorn { get { if (!s_CheckedOSType) { OperatingSystem OS = Environment.OSVersion; s_IsLonghorn = OS.Platform == PlatformID.Win32NT && OS.Version.Major >= 6; s_CheckedOSType = true; } return s_IsLonghorn; } } #endif internal static bool IsW2k3 { get { if (!s_CheckedOSW2k3) { OperatingSystem OS = Environment.OSVersion; s_IsW2k3 = ( (OS.Platform == PlatformID.Win32NT) && (OS.Version.Major == 5) && (OS.Version.Minor == 2)); s_CheckedOSW2k3 = true; } return s_IsW2k3; } } internal static bool RunningOnWinNT { get { return OSVersion.Platform == PlatformID.Win32NT; } } [Serializable] internal enum OSName { Invalid = 0, Unknown = 1, Win9x = 0x40, Win95 = 1 | Win9x, Win98 = 2 | Win9x, WinMe = 3 | Win9x, WinNT = 0x80, Nt4 = 1 | WinNT, Win2k = 2 | WinNT } internal static OSName OSInfo { get { if (m_osname == OSName.Invalid) { lock(InternalSyncObject) { if (m_osname == OSName.Invalid) { Microsoft.Win32.Win32Native.OSVERSIONINFO osvi = new Microsoft.Win32.Win32Native.OSVERSIONINFO(); bool r = Win32Native.GetVersionEx(osvi); if (!r) { BCLDebug.Assert(r, "OSVersion native call failed."); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GetVersion")); } switch (osvi.PlatformId) { case Win32Native.VER_PLATFORM_WIN32_NT: switch(osvi.MajorVersion) { case 5: m_osname = OSName.Win2k; break; case 4: m_osname = OSName.Nt4; break; default: m_osname = OSName.WinNT; break; } break; case Win32Native.VER_PLATFORM_WIN32_WINDOWS: switch(osvi.MajorVersion) { case 5: m_osname = OSName.WinMe; break; case 4: if (osvi.MinorVersion == 0) m_osname = OSName.Win95; else m_osname = OSName.Win98; break; default: m_osname = OSName.Win9x; break; } break; default: m_osname = OSName.Unknown; // Unknown OS break; } } } } return m_osname; } } #endif // !FEATURE_PAL // This needs to be removed in a future release. internal static bool IsWin9X() { #if FEATURE_PAL return false; #else return Environment.OSVersion.Platform == PlatformID.Win32Windows; #endif // FEATURE_PAL } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool nativeIsWin9x(); /*==================================StackTrace================================== **Action: **Returns: **Arguments: **Exceptions: ==============================================================================*/ public static String StackTrace { get { new EnvironmentPermission(PermissionState.Unrestricted).Demand(); return GetStackTrace(null, true); } } internal static String GetStackTrace(Exception e, bool needFileInfo) { // Note: Setting needFileInfo to true will start up COM and set our // apartment state. Try to not call this when passing "true" // before the EE's ExecuteMainMethod has had a chance to set up the // apartment state. -- StackTrace st; if (e == null) st = new StackTrace(needFileInfo); else st = new StackTrace(e, needFileInfo); // Do no include a trailing newline for backwards compatibility return st.ToString( System.Diagnostics.StackTrace.TraceFormat.Normal ); } private static void InitResourceHelper() { // Only the default AppDomain should have a ResourceHelper. All calls to // GetResourceString from any AppDomain delegate to GetResourceStringLocal // in the default AppDomain via the fcall GetResourceFromDefault. // Use Thread.BeginCriticalRegion to tell the CLR all managed // allocations within this block are appdomain-critical. // Use a CER to ensure we always exit this region. bool enteredRegion = false; bool tookLock = false; RuntimeHelpers.PrepareConstrainedRegions(); try { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { Thread.BeginCriticalRegion(); enteredRegion = true; Monitor.Enter(Environment.InternalSyncObject); tookLock = true; } if (m_resHelper == null) { ResourceHelper rh = new ResourceHelper(); System.Threading.Thread.MemoryBarrier(); m_resHelper =rh; } } finally { if (tookLock) Monitor.Exit(Environment.InternalSyncObject); if (enteredRegion) Thread.EndCriticalRegion(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static String GetResourceFromDefault(String key); // Looks up the resource string value for key. // // if you change this method's signature then you must change the code that calls it // in excep.cpp and probably you will have to visit mscorlib.h to add the new signature // as well as metasig.h to create the new signature type internal static String GetResourceStringLocal(String key) { if (m_resHelper == null) InitResourceHelper(); return m_resHelper.GetResourceString(key); } [ResourceExposure(ResourceScope.None)] internal static String GetResourceString(String key) { return GetResourceFromDefault(key); } [ResourceExposure(ResourceScope.None)] internal static String GetResourceString(String key, params Object[]values) { String s = GetResourceFromDefault(key); return String.Format(CultureInfo.CurrentCulture, s, values); } public static bool HasShutdownStarted { get { return nativeHasShutdownStarted(); } } [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool nativeHasShutdownStarted(); // This is the temporary Whidbey stub for compatibility flags [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool GetCompatibilityFlag(CompatibilityFlag flag); public static string UserName { get { new EnvironmentPermission(EnvironmentPermissionAccess.Read,"UserName").Demand(); StringBuilder sb = new StringBuilder(256); int size = sb.Capacity; Win32Native.GetUserName(sb, ref size); return sb.ToString(); } } #if !FEATURE_PAL // Note that this is a handle to a process window station, but it does // not need to be closed. CloseWindowStation would ignore this handle. // We also do handle equality checking as well. This isn't a great fit // for SafeHandle. We don't gain anything by using SafeHandle here. private static IntPtr processWinStation; // Doesn't need to be initialized as they're zero-init. private static bool isUserNonInteractive; public static bool UserInteractive { [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] get { if ((OSInfo & OSName.WinNT) == OSName.WinNT) { // On WinNT IntPtr hwinsta = Win32Native.GetProcessWindowStation(); if (hwinsta != IntPtr.Zero && processWinStation != hwinsta) { int lengthNeeded = 0; Win32Native.USEROBJECTFLAGS flags = new Win32Native.USEROBJECTFLAGS(); if (Win32Native.GetUserObjectInformation(hwinsta, Win32Native.UOI_FLAGS, flags, Marshal.SizeOf(flags),ref lengthNeeded)) { if ((flags.dwFlags & Win32Native.WSF_VISIBLE) == 0) { isUserNonInteractive = true; } } processWinStation = hwinsta; } } // The logic is reversed to avoid static initialization to true return !isUserNonInteractive; } } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public static string GetFolderPath(SpecialFolder folder) { if (!Enum.IsDefined(typeof(SpecialFolder),folder)) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Arg_EnumIllegalVal"), (int)folder)); StringBuilder sb = new StringBuilder(Path.MAX_PATH); Win32Native.SHGetFolderPath(IntPtr.Zero, (int) folder, IntPtr.Zero, Win32Native.SHGFP_TYPE_CURRENT, sb); String s = sb.ToString(); new FileIOPermission( FileIOPermissionAccess.PathDiscovery, s ).Demand(); return s; } 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); int domainNameLen = domainName.Capacity; int peUse; // Note: This doesn't work on Win9x. We can implement this // functionality on Win9x by writing a 16 bit DLL and // calling the LAN Manager method NetWkstaGetInfo(). See // http://support.microsoft.com/support/kb/articles/Q155/6/98.asp // We don't have the time to implement this in V1. Hopefully // by the time V2 rolls around, everyone will run Windows XP. byte ret; if (OSVersion.Platform == PlatformID.Win32NT) { 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 = domainName.Capacity; } bool success = Win32Native.LookupAccountName(null, UserName, sid, ref sidLen, domainName, ref domainNameLen, out peUse); if (!success) { int hr = Marshal.GetLastWin32Error(); if (hr == Win32Native.ERROR_CALL_NOT_IMPLEMENTED) throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_Win9x")); throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UserDomainName")); } return domainName.ToString(); } } [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, // // 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, } #endif // !FEATURE_PAL } }
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SafeEventLogReadHandle.cs
- FailedToStartupUIException.cs
- WebPartAuthorizationEventArgs.cs
- GenericWebPart.cs
- ObjectResult.cs
- SchemaTableColumn.cs
- ExternalException.cs
- WebPartCancelEventArgs.cs
- XmlSchemaSimpleTypeRestriction.cs
- OracleCommandSet.cs
- XmlSchemaComplexContent.cs
- InputLanguageSource.cs
- OdbcReferenceCollection.cs
- SqlTriggerContext.cs
- WebReferencesBuildProvider.cs
- CopyNamespacesAction.cs
- ApplicationContext.cs
- LoginCancelEventArgs.cs
- SetStateEventArgs.cs
- ResourceAttributes.cs
- HashCodeCombiner.cs
- RuleProcessor.cs
- QueryPageSettingsEventArgs.cs
- codemethodreferenceexpression.cs
- UnmanagedMemoryAccessor.cs
- PeerCustomResolverBindingElement.cs
- ResolveDuplex11AsyncResult.cs
- TableDetailsRow.cs
- DbParameterHelper.cs
- Figure.cs
- NetDataContractSerializer.cs
- FindCriteriaApril2005.cs
- DataServiceContext.cs
- SortedDictionary.cs
- ParameterBuilder.cs
- MethodCallExpression.cs
- FastPropertyAccessor.cs
- FormsIdentity.cs
- GenericIdentity.cs
- SharedDp.cs
- MonikerSyntaxException.cs
- MatrixAnimationUsingKeyFrames.cs
- LabelDesigner.cs
- SvcMapFileSerializer.cs
- IntSecurity.cs
- DesignerOptionService.cs
- Dynamic.cs
- PathFigure.cs
- TypeDependencyAttribute.cs
- SubMenuStyle.cs
- Stylus.cs
- SymbolResolver.cs
- QueueProcessor.cs
- DBCommandBuilder.cs
- DetailsViewInsertEventArgs.cs
- ViewPort3D.cs
- PhonemeEventArgs.cs
- TextEditorTyping.cs
- MD5CryptoServiceProvider.cs
- TriggerAction.cs
- MultiView.cs
- PostBackTrigger.cs
- ClientScriptItem.cs
- QilLoop.cs
- StringConverter.cs
- SkipQueryOptionExpression.cs
- DaylightTime.cs
- WpfMemberInvoker.cs
- Panel.cs
- TextModifierScope.cs
- VectorValueSerializer.cs
- ObjectViewEntityCollectionData.cs
- GroupQuery.cs
- SafeCertificateStore.cs
- FrameworkRichTextComposition.cs
- HtmlElementErrorEventArgs.cs
- SeekStoryboard.cs
- hwndwrapper.cs
- SourceLocation.cs
- DeadCharTextComposition.cs
- CatalogPart.cs
- HttpConfigurationSystem.cs
- OleDbPermission.cs
- SByte.cs
- SafeNativeMethods.cs
- PrintDialog.cs
- FilePrompt.cs
- TablePatternIdentifiers.cs
- ControlParameter.cs
- XMLSchema.cs
- NavigationProperty.cs
- ResourcesGenerator.cs
- ZoneButton.cs
- ContentElement.cs
- HandlerFactoryWrapper.cs
- CqlParser.cs
- HMACSHA512.cs
- CompositeFontFamily.cs
- ScrollEventArgs.cs
- SqlResolver.cs