HttpRuntime.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / HttpRuntime.cs / 13 / HttpRuntime.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * The ASP.NET runtime services 
 *
 * Copyright (c) 1998 Microsoft Corporation 
 */

namespace System.Web {
    using System.Text; 
    using System.Threading;
    using System.Data; 
    using System.Data.Common; 
    using System.IO;
    using System.Collections; 
    using System.Configuration;
    using System.Globalization;
    using System.Net;
    using System.Xml; 
    using System.Reflection;
    using System.Resources; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Policy; 
    using System.Web;
    using System.Web.UI;
#if ORCAS
    using System.Web.UI.Imaging; 
#endif
    using System.Web.Compilation; 
    using System.Web.Util; 
    using System.Web.Configuration;
    using System.Web.Caching; 
    using System.Web.Hosting;
    using System.Web.Security;
    using System.Web.Management;
    using System.Runtime.Remoting.Messaging; 
    using Microsoft.Win32;
    using System.Security.Cryptography; 
    using System.Security.Principal; 
    using System.Runtime.InteropServices;
 

    /// 
    ///    Provides a set of ASP.NET runtime services.
    ///  
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public sealed class HttpRuntime { 
 
        private const string codegenDirName = "Temporary ASP.NET Files";
 
        private static HttpRuntime _theRuntime;   // single instance of the class
        internal static byte[] s_autogenKeys = new byte[88];

        // 
        // Names of special ASP.NET directories
        // 
 
        internal const string BinDirectoryName = "bin";
        internal const string CodeDirectoryName = "App_Code"; 
        internal const string WebRefDirectoryName = "App_WebReferences";
        internal const string ResourcesDirectoryName = "App_GlobalResources";
        internal const string LocalResourcesDirectoryName = "App_LocalResources";
        internal const string DataDirectoryName = "App_Data"; 
        internal const string ThemesDirectoryName = "App_Themes";
        internal const string GlobalThemesDirectoryName = "Themes"; 
        internal const string BrowsersDirectoryName = "App_Browsers"; 

        private static string DirectorySeparatorString = new string(Path.DirectorySeparatorChar, 1); 
        private static string DoubleDirectorySeparatorString = new string(Path.DirectorySeparatorChar, 2);


#if OLD 
        // For s_forbiddenDirs and s_forbiddenDirsConstant, see
        // ndll.h, and RestrictIISFolders in regiis.cxx 
 
        internal static string[]    s_forbiddenDirs =   {
                                        BinDirectoryName, 
                                        CodeDirectoryName,
                                        DataDirectoryName,
                                        ResourcesDirectoryName,
                                        WebRefDirectoryName, 
                                    };
 
        internal static Int32[]     s_forbiddenDirsConstant = { 
                                        UnsafeNativeMethods.RESTRICT_BIN,
                                        UnsafeNativeMethods.RESTRICT_CODE, 
                                        UnsafeNativeMethods.RESTRICT_DATA,
                                        UnsafeNativeMethods.RESTRICT_RESOURCES,
                                        UnsafeNativeMethods.RESTRICT_WEBREFERENCES,
                                    }; 
#endif
 
        static HttpRuntime() { 
            AddAppDomainTraceMessage("*HttpRuntime::cctor");
 
            StaticInit();

            _theRuntime = new HttpRuntime();
 
            _theRuntime.Init();
 
            AddAppDomainTraceMessage("HttpRuntime::cctor*"); 
        }
 
        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public HttpRuntime() {
        }
 
        //
        // static initialization to get hooked up to the unmanaged code 
        // get installation directory, etc. 
        //
 
        private static bool s_initialized = false;
        private static String s_installDirectory;
        private static bool s_isEngineLoaded = false;
 
        // Force the static initialization of this class.
        internal static void ForceStaticInit() { } 
 
        private static void StaticInit() {
            if (s_initialized) { 
                // already initialized
                return;
            }
 
            bool isEngineLoaded = false;
            String installDir = null; 
 
            // load webengine.dll if it is not loaded already
 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features

            installDir = RuntimeEnvironment.GetRuntimeDirectory();
 
            if (UnsafeNativeMethods.GetModuleHandle(ModName.ENGINE_FULL_NAME) != IntPtr.Zero) {
                isEngineLoaded = true; 
            } 

            // Load webengine.dll if not loaded already 

            if (!isEngineLoaded) {
                String fullPath = installDir + Path.DirectorySeparatorChar + ModName.ENGINE_FULL_NAME;
 
                if (UnsafeNativeMethods.LoadLibrary(fullPath) != IntPtr.Zero) {
                    isEngineLoaded = true; 
                } 
            }
 
            if (isEngineLoaded) {
                UnsafeNativeMethods.InitializeLibrary();
            }
 
#else // !FEATURE_PAL

            string p = typeof(object).Module.FullyQualifiedName; 
            installDir = Path.GetDirectoryName(p);
#endif // !FEATURE_PAL 

            s_installDirectory = installDir;
            s_isEngineLoaded = isEngineLoaded;
            s_initialized = true; 

            AddAppDomainTraceMessage("Initialize"); 
        } 

        // 
        // Runtime services
        //

        private NamedPermissionSet _namedPermissionSet; 
        private FileChangesMonitor _fcm;
        private CacheInternal _cacheInternal; 
        private Cache _cachePublic; 
        private bool _isOnUNCShare;
        private Profiler _profiler; 
        private RequestTimeoutManager _timeoutManager;
        private RequestQueue _requestQueue;
        private bool _apartmentThreading;
 
#if ORCAS
        private IHttpDataStorageProvider _httpDataStorageProvider; 
        private HttpDataStorageCleanup _httpDataStorageCleanup; 
#endif
 
#if SITECOUNTERS
        private SiteCounters            _siteCounters;
#endif
        private bool _processRequestInApplicationTrust; 
        //
        // Counters 
        // 

        private bool _beforeFirstRequest = true; 
        private DateTime _firstRequestStartTime;
        private bool _firstRequestCompleted;
        private bool _userForcedShutdown;
        private bool _configInited; 
        private bool _fusionInited;
        private int _activeRequestCount; 
        private DateTime _lastShutdownAttemptTime; 
        private bool _shutdownInProgress;
        private String _shutDownStack; 
        private String _shutDownMessage;
        private ApplicationShutdownReason _shutdownReason = ApplicationShutdownReason.None;
        private string _trustLevel;
        private string _wpUserId; 
        private bool _shutdownWebEventRaised;
 
        // 
        // Header Newlines
        // 
        private bool _enableHeaderChecking;

        //
        // Callbacks 
        //
 
        private AsyncCallback _requestNotificationCompletionCallback; 
        private AsyncCallback _handlerCompletionCallback;
        private HttpWorkerRequest.EndOfSendNotification _asyncEndOfSendCallback; 
        private WaitCallback _appDomainUnloadallback;

        //
        // Initialization error (to be reported on subsequent requests) 
        //
 
        private Exception _initializationError; 
        private bool _hostingInitFailed; // make such errors non-sticky
        private Timer _appDomainShutdownTimer = null; 


        //
        // App domain related 
        //
 
        private String _tempDir; 
        private String _codegenDir;
        private String _appDomainAppId; 
        private String _appDomainAppPath;
        private VirtualPath _appDomainAppVPath;
        private String _appDomainId;
 
        //
        // Debugging support 
        // 

        private bool _debuggingEnabled = false; 

        //
        // App_Offline.htm support
        // 

        private const string AppOfflineFileName = "App_Offline.htm"; 
        private const long MaxAppOfflineFileLength = 1024 * 1024; 
        private byte[] _appOfflineMessage;
 
        //
        // Client script support
        //
 
        private const string AspNetClientFilesSubDirectory = "asp.netclientfiles";
        private const string AspNetClientFilesParentVirtualPath = "/aspnet_client/system_web/"; 
        private string _clientScriptVirtualPath; 
        private string _clientScriptPhysicalPath;
 
        //
        //  Integrated pipeline mode
        //
        private static bool _useIntegratedPipeline; 

        ///////////////////////////////////////////////////////////////////////// 
        // 3 steps of initialization: 
        //     Init() is called from HttpRuntime cctor
        //     HostingInit() is called by the Hosting Environment 
        //     FirstRequestInit() is called on first HTTP request
        //

        /* 
         * Context-less initialization (on app domain creation)
         */ 
        private void Init() { 
            try {
#if !FEATURE_PAL 
                if (Environment.OSVersion.Platform != PlatformID.Win32NT)
                    throw new PlatformNotSupportedException(SR.GetString(SR.RequiresNT));
#else // !FEATURE_PAL
                // ROTORTODO 
                // Do nothing: FEATURE_PAL environment will always support ASP.NET hosting
#endif // !FEATURE_PAL 
 

 
                _profiler = new Profiler();
                _timeoutManager = new RequestTimeoutManager();
                _wpUserId = GetCurrentUserName();
 
                _requestNotificationCompletionCallback = new AsyncCallback(this.OnRequestNotificationCompletion);
                _handlerCompletionCallback = new AsyncCallback(this.OnHandlerCompletion); 
                _asyncEndOfSendCallback = new HttpWorkerRequest.EndOfSendNotification(this.EndOfSendCallback); 
                _appDomainUnloadallback = new WaitCallback(this.ReleaseResourcesAndUnloadAppDomain);
 

                // appdomain values
                if (GetAppDomainString(".appDomain") != null) {
 
                    Debug.Assert(HostingEnvironment.IsHosted);
 
                    _appDomainAppId = GetAppDomainString(".appId"); 
                    _appDomainAppPath = GetAppDomainString(".appPath");
                    _appDomainAppVPath = VirtualPath.CreateNonRelativeTrailingSlash(GetAppDomainString(".appVPath")); 
                    _appDomainId = GetAppDomainString(".domainId");

                    _isOnUNCShare = StringUtil.StringStartsWith(_appDomainAppPath, "\\\\");
 
                    // init perf counters for this appdomain
                    PerfCounters.Open(_appDomainAppId); 
                } 
                else {
                    Debug.Assert(!HostingEnvironment.IsHosted); 
                }

                // _appDomainAppPath should be set before file change notifications are initialized
                _fcm = new FileChangesMonitor(); 
            }
            catch (Exception e) { 
                // remember static initalization error 
                InitializationException = e;
            } 
        }

        private void SetUpDataDirectory() {
 
            // Set the DataDirectory (see VSWhidbey 226834) with permission (DevDiv 29614)
            string dataDirectory = Path.Combine(_appDomainAppPath, DataDirectoryName); 
            AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory, 
                    new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDirectory));
        } 

        private void DisposeAppDomainShutdownTimer() {
            Timer timer = _appDomainShutdownTimer;
            if (timer != null && Interlocked.CompareExchange(ref _appDomainShutdownTimer, null, timer) == timer) { 
                timer.Dispose();
            } 
        } 

        private void AppDomainShutdownTimerCallback(Object state) { 
            try {
                DisposeAppDomainShutdownTimer();
                ShutdownAppDomain(ApplicationShutdownReason.InitializationError, "Initialization Error");
            } 
            catch { } // ignore exceptions
        } 
 
        /*
         * Restart the AppDomain in 10 seconds 
         */
        private void StartAppDomainShutdownTimer() {
            if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
                lock (this) { 
                    if (_appDomainShutdownTimer == null && !_shutdownInProgress) {
                        _appDomainShutdownTimer = new Timer( 
                            new TimerCallback(this.AppDomainShutdownTimerCallback), 
                            null,
                            10 * 1000, 
                            0);
                    }
                }
            } 
        }
 
 
        /*
         * Initialization from HostingEnvironment of HTTP independent features 
         */
        private void HostingInit(HostingEnvironmentFlags hostingFlags) {
            using (new ApplicationImpersonationContext()) {
                try { 
                    // To ignore FCN during initialization
                    _firstRequestStartTime = DateTime.UtcNow; 
 
                    SetUpDataDirectory();
 
                    // Throw an exception about lack of access to app directory early on
                    EnsureAccessToApplicationDirectory();

                    // Monitor renames to directories we are watching, and notifications on the bin directory 
                    //
                    // Note that this must be the first monitoring that we do of the application directory. 
                    // There is a bug in Windows 2000 Server where notifications on UNC shares do not 
                    // happen correctly if:
                    //      1. the directory is monitored for regular notifications 
                    //      2. the directory is then monitored for directory renames
                    //      3. the directory is monitored again for regular notifications
                    StartMonitoringDirectoryRenamesAndBinDirectory();
 
                    //
                    // Get the configuration needed to minimally initialize 
                    // the components required for a complete configuration system, 
                    // especially SetTrustLevel.
                    // 
                    // We want to do this before calling SetUpCodegenDirectory(),
                    // to remove the risk of the config system loading
                    // codegen assemblies in full trust (VSWhidbey 460506)
                    // 
                    CacheSection cacheSection;
                    TrustSection trustSection; 
                    SecurityPolicySection securityPolicySection; 
                    CompilationSection compilationSection;
                    HostingEnvironmentSection hostingEnvironmentSection; 
                    Exception configInitException;

                    GetInitConfigSections(
                            out cacheSection, 
                            out trustSection,
                            out securityPolicySection, 
                            out compilationSection, 
                            out hostingEnvironmentSection,
                            out configInitException); 

                    // Once the configuration system is initialized, we can read
                    // the cache configuration settings.
                    // 
                    // Note that we must do this after we start monitoring directory renames,
                    // as reading config will cause file monitoring on the application directory 
                    // to occur. 
                    HttpRuntime.CacheInternal.ReadCacheInternalConfig(cacheSection);
 
                    // Set up the codegen directory for the app.  This needs to be done before we process
                    // the policy file, because it needs to replace the $CodeGen$ token.
                    SetUpCodegenDirectory(compilationSection);
 
                    // NOTE: after calling SetUpCodegenDirectory(), and until we call SetTrustLevel(), we are at
                    // risk of codegen assemblies being loaded in full trust.  No code that might cause 
                    // assembly loading should be added here! 

                    try { 
                        // Set code access policy on the app domain
                        SetTrustLevel(trustSection, securityPolicySection);

                    } 
                    catch {
                        // throw the original config exception if it exists 
                        if (configInitException != null) { 
                            throw configInitException;
                        } 
                        throw;
                    }

                    // Configure fusion to use directories set in the app config 
                    InitFusion(hostingEnvironmentSection);
 
                    // Complete initialization of configuration. 
                    // Note that this needs to be called after SetTrustLevel,
                    // as it indicates that we have the permission set needed 
                    // to correctly run configuration section handlers.
                    // As little config should be read before CompleteInit() as possible.
                    // No section that runs before CompleteInit() should demand permissions,
                    // as the permissions set has not yet determined until SetTrustLevel() 
                    // is called.
                    HttpConfigurationSystem.CompleteInit(); 
 
                    //
                    // If an exception occurred loading configuration, 
                    // we are now ready to handle exception processing
                    // with the correct trust level set.
                    //
                    if (configInitException != null) { 
                        throw configInitException;
                    } 
 
                    SetThreadPoolLimits();
 
                    SetAutogenKeys();

                    // Initialize the build manager
                    BuildManager.InitializeBuildManager(); 

                    // Determine apartment threading setting 
                    InitApartmentThreading(); 

                    // Init debugging 
                    InitDebuggingSupport();
#if SITECOUNTERS
                    if (!BuildManagerHost.InClientBuildManager) {
                        // create siteCounters object according to config 
                        InitSiteCounters();
                    } 
#endif 
                    _processRequestInApplicationTrust = trustSection.ProcessRequestInApplicationTrust;
                } 
                catch (Exception e) {
                    _hostingInitFailed = true;
                    InitializationException = e;
 
                    Debug.Trace("AppDomainFactory", "HostingInit failed. " + e.ToString());
 
                    if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0) 
                        throw;
                } 
            }
        }

        internal static Exception InitializationException { 
            get {
                return _theRuntime._initializationError; 
            } 

            // The exception is "cached" for 10 seconds, then the AppDomain is restarted. 
            set {
                _theRuntime._initializationError = value;
                // In v2.0, we shutdown immediately if hostingInitFailed...so we don't need the timer
                if (!HostingInitFailed) { 
                    _theRuntime.StartAppDomainShutdownTimer();
                } 
            } 
        }
 
        internal static bool HostingInitFailed {
            get {
                return _theRuntime._hostingInitFailed;
            } 
        }
 
        internal static void InitializeHostingFeatures(HostingEnvironmentFlags hostingFlags) { 
            _theRuntime.HostingInit(hostingFlags);
        } 

        internal static bool EnableHeaderChecking {
            get {
                return _theRuntime._enableHeaderChecking; 
            }
        } 
 
        internal static bool ProcessRequestInApplicationTrust {
            get { 
                return _theRuntime._processRequestInApplicationTrust;
            }
        }
 
        internal static byte[] AppOfflineMessage {
            get { 
                return _theRuntime._appOfflineMessage; 
            }
        } 

        /*
         * Initialization on first request (context available)
         */ 
        private void FirstRequestInit(HttpContext context) {
            Exception error = null; 
 
            if (InitializationException == null && _appDomainId != null) {
#if DBG 
                HttpContext.SetDebugAssertOnAccessToCurrent(true);
#endif
                try {
                    using (new ApplicationImpersonationContext()) { 
                        // Is this necessary?  See InitHttpConfiguration
                        CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture; 
                        CultureInfo savedUICulture = Thread.CurrentThread.CurrentUICulture; 

                        try { 
                            // Ensure config system is initialized
                            InitHttpConfiguration(); // be sure config system is set

                            // Check if applicaton is enabled 
                            CheckApplicationEnabled();
 
                            // Check access to temp compilation directory (under hosting identity) 
                            CheckAccessToTempDirectory();
 
                            // Initialize health monitoring
                            InitializeHealthMonitoring();

                            // Init request queue (after reading config) 
                            InitRequestQueue();
 
                            // configure the profiler according to config 
                            InitTrace(context);
 
#if ORCAS
                            // Initialize the HttpDataStore and cleanup process
                            InitHttpDataStore();
#endif 

                            // Start heatbeat for Web Event Health Monitoring 
                            HealthMonitoringManager.StartHealthMonitoringHeartbeat(); 

                            // Remove read and browse access of the bin directory 
                            RestrictIISFolders(context);

                            // Preload all assemblies from bin (only if required).  ASURT 114486
                            PreloadAssembliesFromBin(); 

                            // Decide whether or not to encode headers.  VsWhidbey 257154 
                            InitHeaderEncoding(); 

                            if (context.WorkerRequest is ISAPIWorkerRequestOutOfProc) { 
                                // Make sure that the  section has no errors
                                ProcessModelSection processModel = RuntimeConfig.GetMachineConfig().ProcessModel;
                            }
                        } 
                        finally {
                            Thread.CurrentThread.CurrentUICulture = savedUICulture; 
                            Thread.CurrentThread.CurrentCulture = savedCulture; 
                        }
                    } 
                }
                catch (ConfigurationException e) {
                    error = e;
                } 
                catch (Exception e) {
                    // remember second-phase initialization error 
                    error = new HttpException(SR.GetString(SR.XSP_init_error, e.Message), e); 
                }
                finally { 
#if DBG
                    HttpContext.SetDebugAssertOnAccessToCurrent(false);
#endif
                } 
            }
 
            if (InitializationException != null) { 
                // throw cached exception.  We need to wrap it in a new exception, otherwise
                // we lose the original stack. 
                throw new HttpException(InitializationException.Message, InitializationException);
            }
            else if (error != null) {
                InitializationException = error; 
                // throw new exception
                throw error; 
            } 

            AddAppDomainTraceMessage("FirstRequestInit"); 
        }

        private void EnsureFirstRequestInit(HttpContext context) {
            if (_beforeFirstRequest) { 
                lock (this) {
                    if (_beforeFirstRequest) { 
                        _firstRequestStartTime = DateTime.UtcNow; 
                        FirstRequestInit(context);
                        _beforeFirstRequest = false; 
                    }
                }
            }
        } 

        private void EnsureAccessToApplicationDirectory() { 
            if (!FileUtil.DirectoryAccessible(_appDomainAppPath)) { 
                //
                if (_appDomainAppPath.IndexOf('?') >= 0) { 
                    // Possible Unicode when not supported
                    throw new HttpException(SR.GetString(SR.Access_denied_to_unicode_app_dir, _appDomainAppPath));
                }
                else { 
                    throw new HttpException(SR.GetString(SR.Access_denied_to_app_dir, _appDomainAppPath));
                } 
            } 
        }
 
        private void StartMonitoringDirectoryRenamesAndBinDirectory() {
            _fcm.StartMonitoringDirectoryRenamesAndBinDirectory(AppDomainAppPathInternal, new FileChangeEventHandler(this.OnCriticalDirectoryChange));
        }
 
        //
        // Monitor a local resources subdirectory and unload appdomain when it changes 
        // 
        internal static void StartListeningToLocalResourcesDirectory(VirtualPath virtualDir) {
#if !FEATURE_PAL // FEATURE_PAL does not enable file change notification 
            _theRuntime._fcm.StartListeningToLocalResourcesDirectory(virtualDir);
#endif // !FEATURE_PAL
        }
 
        //
        // Get the configuration needed to minimally initialize 
        // the components required for a complete configuration system, 
        //
        // Note that if the application configuration file has an error, 
        // AppLKGConfig will still retreive any valid configuration from
        // that file, or from location directives that apply to the
        // application path. This implies that an administrator can
        // lock down an application's trust level in root web.config, 
        // and it will still take effect if the application's web.config
        // has errors. 
        // 
        private void GetInitConfigSections(
                out CacheSection cacheSection, 
                out TrustSection trustSection,
                out SecurityPolicySection securityPolicySection,
                out CompilationSection compilationSection,
                out HostingEnvironmentSection hostingEnvironmentSection, 
                out Exception initException) {
 
            cacheSection = null; 
            trustSection = null;
            securityPolicySection = null; 
            compilationSection = null;
            hostingEnvironmentSection = null;
            initException = null;
 
            // AppLKGConfig is guaranteed to not throw an exception.
            RuntimeConfig appLKGConfig = RuntimeConfig.GetAppLKGConfig(); 
 
            // AppConfig may throw an exception.
            RuntimeConfig appConfig = null; 
            try {
                appConfig = RuntimeConfig.GetAppConfig();
            }
            catch (Exception e) { 
                initException = e;
            } 
 
            // Cache section
            if (appConfig != null) { 
                try {
                    cacheSection = appConfig.Cache;
                }
                catch (Exception e) { 
                    if (initException == null) {
                        initException = e; 
                    } 
                }
            } 

            if (cacheSection == null) {
                cacheSection = appLKGConfig.Cache;
            } 

            // Trust section 
            if (appConfig != null) { 
                try {
                    trustSection = appConfig.Trust; 
                }
                catch (Exception e) {
                    if (initException == null) {
                        initException = e; 
                    }
                } 
            } 

            if (trustSection == null) { 
                trustSection = appLKGConfig.Trust;
            }

            // SecurityPolicy section 
            if (appConfig != null) {
                try { 
                    securityPolicySection = appConfig.SecurityPolicy; 
                }
                catch (Exception e) { 
                    if (initException == null) {
                        initException = e;
                    }
                } 
            }
 
            if (securityPolicySection == null) { 
                securityPolicySection = appLKGConfig.SecurityPolicy;
            } 

            // Compilation section
            if (appConfig != null) {
                try { 
                    compilationSection = appConfig.Compilation;
                } 
                catch (Exception e) { 
                    if (initException == null) {
                        initException = e; 
                    }
                }
            }
 
            if (compilationSection == null) {
                compilationSection = appLKGConfig.Compilation; 
            } 

            // HostingEnvironment section 
            if (appConfig != null) {
                try {
                    hostingEnvironmentSection = appConfig.HostingEnvironment;
                } 
                catch (Exception e) {
                    if (initException == null) { 
                        initException = e; 
                    }
                } 
            }

            if (hostingEnvironmentSection == null) {
                hostingEnvironmentSection = appLKGConfig.HostingEnvironment; 
            }
        } 
 
        // Set up the codegen directory for the app
        private void SetUpCodegenDirectory(CompilationSection compilationSection) { 
            AppDomain appDomain = Thread.GetDomain();

            string codegenBase;
 
            string simpleAppName = System.Web.Hosting.AppManagerAppDomainFactory.ConstructSimpleAppName(
                AppDomainAppVirtualPath); 
 
            string tempDirectory = null;
 
            // These variables are used for error handling
            string tempDirAttribName = null;
            string configFileName = null;
            int configLineNumber = 0; 

            if (compilationSection != null && !String.IsNullOrEmpty(compilationSection.TempDirectory)) { 
                tempDirectory = compilationSection.TempDirectory; 

                compilationSection.GetTempDirectoryErrorInfo(out tempDirAttribName, 
                    out configFileName, out configLineNumber);
            }

            if (tempDirectory != null) { 
                tempDirectory = tempDirectory.Trim();
 
                if (!Path.IsPathRooted(tempDirectory)) { 
                    // Make sure the path is not relative (VSWhidbey 260075)
                    tempDirectory = null; 
                }
                else {
                    try {
                        // Canonicalize it to avoid problems with spaces (VSWhidbey 229873) 
                        tempDirectory = new DirectoryInfo(tempDirectory).FullName;
                    } 
                    catch { 
                        tempDirectory = null;
                    } 
                }

                if (tempDirectory == null) {
                    throw new ConfigurationErrorsException( 
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
                        configFileName, configLineNumber); 
                } 
#if FEATURE_PAL
            } else { 
                System.UInt32 length = 0;
                StringBuilder sb = null;
                bool bRet;
 
                // Get the required length
                bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory, 
                                    null, ref length);
 
                if (true == bRet) {
                    // now, allocate the string
                    sb = new StringBuilder ((int)length);
 
                    // call again to get the value
                    bRet = UnsafeNativeMethods.GetUserTempDirectory( 
                                    UnsafeNativeMethods.DeploymentDirectoryType.ddtInstallationDependentDirectory, 
                                    sb, ref length);
                } 

                if (false == bRet) {
                    throw new ConfigurationException(
                        HttpRuntime.FormatResourceString(SR.Invalid_temp_directory, tempDirAttribName)); 
                }
 
                tempDirectory = Path.Combine(sb.ToString(), codegenDirName); 
            }
 
            // Always try to create the ASP.Net temp directory for FEATURE_PAL
#endif // FEATURE_PAL

                // Create the config-specified directory if needed 
                try {
                    Directory.CreateDirectory(tempDirectory); 
                } 
                catch (Exception e) {
                    throw new ConfigurationErrorsException( 
                        SR.GetString(SR.Invalid_temp_directory, tempDirAttribName),
                        e,
                        configFileName, configLineNumber);
                } 
#if !FEATURE_PAL
            } 
            else { 
                tempDirectory = Path.Combine(s_installDirectory, codegenDirName);
            } 
#endif // !FEATURE_PAL

            // If we don't have write access to the codegen dir, use the TEMP dir instead.
            // This will allow non-admin users to work in hosting scenarios (e.g. Venus, aspnet_compiler) 
            if (!System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory)) {
 
                // Don't do this if we're in a service (!UserInteractive), as TEMP 
                // could point to unwanted places.
 
#if !FEATURE_PAL // always fail here
                if (!Environment.UserInteractive)
#endif // !FEATURE_PAL
 { 
                    throw new HttpException(SR.GetString(SR.No_codegen_access,
                        System.Web.UI.Util.GetCurrentAccountName(), tempDirectory)); 
                } 

                tempDirectory = Path.GetTempPath(); 
                Debug.Assert(System.Web.UI.Util.HasWriteAccessToDirectory(tempDirectory));
                tempDirectory = Path.Combine(tempDirectory, codegenDirName);
            }
 
            _tempDir = tempDirectory;
 
            codegenBase = Path.Combine(tempDirectory, simpleAppName); 

#pragma warning disable 0618    // To avoid deprecation warning 
            appDomain.SetDynamicBase(codegenBase);
#pragma warning restore 0618

            _codegenDir = Thread.GetDomain().DynamicDirectory; 

            // Create the codegen directory if needed 
            Directory.CreateDirectory(_codegenDir); 
        }
 
        private void InitFusion(HostingEnvironmentSection hostingEnvironmentSection) {

            AppDomain appDomain = Thread.GetDomain();
 
            // If there is a double backslash in the string, get rid of it (ASURT 122191)
            // Make sure to skip the first char, to avoid breaking the UNC case 
            string appDomainAppPath = _appDomainAppPath; 
            if (appDomainAppPath.IndexOf(DoubleDirectorySeparatorString, 1, StringComparison.Ordinal) >= 1) {
                appDomainAppPath = appDomainAppPath[0] + appDomainAppPath.Substring(1).Replace(DoubleDirectorySeparatorString, 
                    DirectorySeparatorString);
            }

#pragma warning disable 0618    // To avoid deprecation warning 
            // Allow assemblies from 'bin' to be loaded
            appDomain.AppendPrivatePath(appDomainAppPath + BinDirectoryName); 
#pragma warning restore 0618 

            // If shadow copying was disabled via config, turn it off (DevDiv 30864) 
            if (hostingEnvironmentSection != null && !hostingEnvironmentSection.ShadowCopyBinAssemblies) {
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.ClearShadowCopyPath();
#pragma warning restore 0618 
            }
            else { 
                // enable shadow-copying from bin 
#pragma warning disable 0618    // To avoid deprecation warning
                appDomain.SetShadowCopyPath(appDomainAppPath + BinDirectoryName); 
#pragma warning restore 0618
            }

            // Get rid of the last part of the directory (the app name), since it will 
            // be re-appended.
            string parentDir = Directory.GetParent(_codegenDir).FullName; 
#pragma warning disable 0618    // To avoid deprecation warning 
            appDomain.SetCachePath(parentDir);
#pragma warning restore 0618 

            _fusionInited = true;
        }
 
        private void InitRequestQueue() {
            RuntimeConfig config = RuntimeConfig.GetAppConfig(); 
            HttpRuntimeSection runtimeConfig = config.HttpRuntime; 
            ProcessModelSection processConfig = config.ProcessModel;
 
            if (processConfig.AutoConfig) {
                _requestQueue = new RequestQueue(
                    88 * processConfig.CpuCount,
                    76 * processConfig.CpuCount, 
                    runtimeConfig.AppRequestQueueLimit,
                    processConfig.ClientConnectedCheck); 
            } 
            else {
 
                // Configuration section handlers cannot validate values based on values
                // in other configuration sections, so we validate minFreeThreads and
                // minLocalRequestFreeThreads here.
                int maxThreads = (processConfig.MaxWorkerThreadsTimesCpuCount < processConfig.MaxIoThreadsTimesCpuCount) ? processConfig.MaxWorkerThreadsTimesCpuCount : processConfig.MaxIoThreadsTimesCpuCount; 
                // validate minFreeThreads
                if (runtimeConfig.MinFreeThreads >= maxThreads) { 
                    if (runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber == 0) { 
                        if (processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber != 0) {
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)), 
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].Source,
                                                                   processConfig.ElementInformation.Properties["maxWorkerThreads"].LineNumber);
                        }
                        else { 
                            throw new ConfigurationErrorsException(SR.GetString(SR.Thread_pool_limit_must_be_greater_than_minFreeThreads, runtimeConfig.MinFreeThreads.ToString(CultureInfo.InvariantCulture)),
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].Source, 
                                                                   processConfig.ElementInformation.Properties["maxIoThreads"].LineNumber); 
                        }
                    } 
                    else {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Min_free_threads_must_be_under_thread_pool_limits, maxThreads.ToString(CultureInfo.InvariantCulture)),
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].Source,
                                                               runtimeConfig.ElementInformation.Properties["minFreeThreads"].LineNumber); 
                    }
                } 
                // validate minLocalRequestFreeThreads 
                if (runtimeConfig.MinLocalRequestFreeThreads > runtimeConfig.MinFreeThreads) {
                    if (runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber == 0) { 
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads),
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].Source,
                                                               processConfig.ElementInformation.Properties["minFreeThreads"].LineNumber);
                    } 
                    else {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Local_free_threads_cannot_exceed_free_threads), 
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].Source, 
                                                               runtimeConfig.ElementInformation.Properties["minLocalRequestFreeThreads"].LineNumber);
                    } 
                }

                _requestQueue = new RequestQueue(
                    runtimeConfig.MinFreeThreads, 
                    runtimeConfig.MinLocalRequestFreeThreads,
                    runtimeConfig.AppRequestQueueLimit, 
                    processConfig.ClientConnectedCheck); 
            }
        } 

#if ORCAS
        private void InitHttpDataStore() {
            ImageGenerationSection igConfig = RuntimeConfig.GetAppConfig().ImageGeneration; 
            IDictionary settings = new Hashtable();
            int imageStorageExpiration = 300; 
            StorageType storageType = igConfig.StorageType; 

            if (storageType == StorageType.Disk) { 
                _httpDataStorageProvider = new DiskHttpDataStorageProvider();
                settings["storagePath"] = igConfig.StoragePath;
            }
 
            int imageExp = (int) igConfig.StorageExpiration.TotalSeconds;
            if (imageExp > 0) { 
                imageStorageExpiration = imageExp; 
            }
 
            if (_httpDataStorageProvider == null) {
                _httpDataStorageProvider = new CacheHttpDataStorageProvider();
            }
 
            try {
                _httpDataStorageProvider.Initialize(imageStorageExpiration, settings); 
            } 
            catch (Exception e) {
                throw new ConfigurationErrorsException(e.Message, e, igConfig.SourceFileName, igConfig.SourceLineNumber); 
            }

            _httpDataStorageCleanup = new HttpDataStorageCleanup(imageStorageExpiration * 1000, _httpDataStorageProvider);
        } 
#endif
 
        private void InitApartmentThreading() { 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
 
            if (runtimeConfig != null) {
                _apartmentThreading = runtimeConfig.ApartmentThreading;
            }
            else { 
                _apartmentThreading = false;
            } 
        } 

        private void InitTrace(HttpContext context) { 
            TraceSection traceConfig = RuntimeConfig.GetAppConfig().Trace;

            Profile.RequestsToProfile = traceConfig.RequestLimit;
            Profile.PageOutput = traceConfig.PageOutput; 
            Profile.OutputMode = TraceMode.SortByTime;
            if (traceConfig.TraceMode == TraceDisplayMode.SortByCategory) 
                Profile.OutputMode = TraceMode.SortByCategory; 

            Profile.LocalOnly = traceConfig.LocalOnly; 
            Profile.IsEnabled = traceConfig.Enabled;
            Profile.MostRecent = traceConfig.MostRecent;
            Profile.Reset();
 
            // the first request's context is created before InitTrace, so
            // we need to set this manually. (ASURT 93730) 
            context.TraceIsEnabled = traceConfig.Enabled; 
            TraceContext.SetWriteToDiagnosticsTrace(traceConfig.WriteToDiagnosticsTrace);
        } 

        private void InitDebuggingSupport() {
            CompilationSection compConfig = RuntimeConfig.GetAppConfig().Compilation;
            _debuggingEnabled = compConfig.Debug; 
        }
 
#if SITECOUNTERS 
        internal void InitSiteCounters() {
            SiteCountersSection siteCountersConfig = RuntimeConfig.GetAppConfig().SiteCounters; 
            Type type;
#if FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
 		siteCountersConfig.Enabled = false;
#endif // FEATURE_PAL 
            if (siteCountersConfig.Enabled) {
                type = siteCountersConfig.TypeInternal; 
            } 
            else {
                type = BuildManager.GetType("System.Web.SiteCounters", true, false); 
            }

            _siteCounters = (SiteCounters) CreateNonPublicInstance(type);
            _siteCounters.Initialize(); 
        }
#endif 
        /* 
         * Pre-load all the bin assemblies if we're impersonated.  This way, if user code
         * calls Assembly.Load while impersonated, the assembly will already be loaded, and 
         * we won't fail due to lack of permissions on the codegen dir (see ASURT 114486)
         */
        private void PreloadAssembliesFromBin() {
            bool appClientImpersonationEnabled = false; 

            if (!_isOnUNCShare) { 
                // if not on UNC share check if config has impersonation enabled (without userName) 
                IdentitySection c = RuntimeConfig.GetAppConfig().Identity;
                if (c.Impersonate && c.ImpersonateToken == IntPtr.Zero) 
                    appClientImpersonationEnabled = true;
            }

            if (!appClientImpersonationEnabled) 
                return;
 
            // Get the path to the bin directory 
            string binPath = HttpRuntime.BinDirectoryInternal;
 
            DirectoryInfo binPathDirectory = new DirectoryInfo(binPath);

            if (!binPathDirectory.Exists)
                return; 

            PreloadAssembliesFromBinRecursive(binPathDirectory); 
        } 

        private void PreloadAssembliesFromBinRecursive(DirectoryInfo dirInfo) { 

            FileInfo[] binDlls = dirInfo.GetFiles("*.dll");

            // Pre-load all the assemblies, ignoring all exceptions 
            foreach (FileInfo fi in binDlls) {
                try { Assembly.Load(System.Web.UI.Util.GetAssemblyNameFromFileName(fi.Name)); } 
                catch (FileNotFoundException) { 
                    // If Load failed, try LoadFrom (VSWhidbey 493725)
                    try { Assembly.LoadFrom(fi.FullName); } 
                    catch { }
                }
                catch { }
            } 

            // Recurse on the subdirectories 
            DirectoryInfo[] subDirs = dirInfo.GetDirectories(); 
            foreach (DirectoryInfo di in subDirs) {
                PreloadAssembliesFromBinRecursive(di); 
            }
        }

        private void SetAutoConfigLimits(ProcessModelSection pmConfig) { 
            // check if the current limits are ok
            int workerMax, ioMax; 
            ThreadPool.GetMaxThreads(out workerMax, out ioMax); 

            // only set if different 
            if (pmConfig.DefaultMaxWorkerThreadsForAutoConfig != workerMax || pmConfig.DefaultMaxIoThreadsForAutoConfig != ioMax) {
                Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.DefaultMaxWorkerThreadsForAutoConfig + "," + pmConfig.DefaultMaxIoThreadsForAutoConfig);
                UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.DefaultMaxWorkerThreadsForAutoConfig, pmConfig.DefaultMaxIoThreadsForAutoConfig);
            } 

            // this is the code equivalent of setting maxconnection 
            System.Net.ServicePointManager.DefaultConnectionLimit = 12 * pmConfig.CpuCount; 

            // we call InitRequestQueue later, from FirstRequestInit, and set minFreeThreads and minLocalRequestFreeThreads 
        }

        private void SetThreadPoolLimits() {
            try { 
                ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel;
 
                if (pmConfig.AutoConfig) { 
                    // use recommendation in http://support.microsoft.com/?id=821268
                    SetAutoConfigLimits(pmConfig); 
                }
                else if (pmConfig.MaxWorkerThreadsTimesCpuCount > 0 && pmConfig.MaxIoThreadsTimesCpuCount > 0) {
                    // check if the current limits are ok
                    int workerMax, ioMax; 
                    ThreadPool.GetMaxThreads(out workerMax, out ioMax);
 
                    // only set if different 
                    if (pmConfig.MaxWorkerThreadsTimesCpuCount != workerMax || pmConfig.MaxIoThreadsTimesCpuCount != ioMax) {
                        Debug.Trace("ThreadPool", "SetThreadLimit: from " + workerMax + "," + ioMax + " to " + pmConfig.MaxWorkerThreadsTimesCpuCount + "," + pmConfig.MaxIoThreadsTimesCpuCount); 
                        UnsafeNativeMethods.SetClrThreadPoolLimits(pmConfig.MaxWorkerThreadsTimesCpuCount, pmConfig.MaxIoThreadsTimesCpuCount);
                    }
                }
 
                if (pmConfig.MinWorkerThreadsTimesCpuCount > 0 || pmConfig.MinIoThreadsTimesCpuCount > 0) {
                    int currentMinWorkerThreads, currentMinIoThreads; 
                    ThreadPool.GetMinThreads(out currentMinWorkerThreads, out currentMinIoThreads); 

                    int newMinWorkerThreads = pmConfig.MinWorkerThreadsTimesCpuCount > 0 ? pmConfig.MinWorkerThreadsTimesCpuCount : currentMinWorkerThreads; 
                    int newMinIoThreads = pmConfig.MinIoThreadsTimesCpuCount > 0 ? pmConfig.MinIoThreadsTimesCpuCount : currentMinIoThreads;

                    if (newMinWorkerThreads > 0 && newMinIoThreads > 0
                        && (newMinWorkerThreads != currentMinWorkerThreads || newMinIoThreads != currentMinIoThreads)) 
                        ThreadPool.SetMinThreads(newMinWorkerThreads, newMinIoThreads);
                } 
            } 
            catch {
            } 
        }

        internal static void CheckApplicationEnabled() {
            // process App_Offline.htm file 
            string appOfflineFile = Path.Combine(_theRuntime._appDomainAppPath, AppOfflineFileName);
            bool appOfflineFileFound = false; 
 
            // monitor even if doesn't exist
            _theRuntime._fcm.StartMonitoringFile(appOfflineFile, new FileChangeEventHandler(_theRuntime.OnAppOfflineFileChange)); 

            // read the file into memory
            try {
                if (File.Exists(appOfflineFile)) { 
                    Debug.Trace("AppOffline", "File " + appOfflineFile + " exists. Using it.");
 
                    using (FileStream fs = new FileStream(appOfflineFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { 
                        if (fs.Length <= MaxAppOfflineFileLength) {
                            int length = (int)fs.Length; 

                            if (length > 0) {
                                byte[] message = new byte[length];
 
                                if (fs.Read(message, 0, length) == length) {
                                    // remember the message 
                                    _theRuntime._appOfflineMessage = message; 
                                    appOfflineFileFound = true;
                                } 
                            }
                            else {
                                // empty file
                                appOfflineFileFound = true; 
                            }
                        } 
                    } 
                }
            } 
            catch {
                // ignore any IO errors reading the file
            }
 
            // throw if there is a valid App_Offline file
            if (appOfflineFileFound) { 
                throw new HttpException(404, String.Empty); 
            }
 
            // process the config setting
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            if (!runtimeConfig.Enable) {
                // throw 404 on first request init -- this will get cached until config changes 
                throw new HttpException(404, String.Empty);
            } 
        } 

        private void CheckAccessToTempDirectory() { 
            // The original check (in HostingInit) was done under process identity
            // this time we do it under hosting identity
            if (HostingEnvironment.HasHostingIdentity) {
                using (new ApplicationImpersonationContext()) { 
                    if (!System.Web.UI.Util.HasWriteAccessToDirectory(_tempDir)) {
                        throw new HttpException(SR.GetString(SR.No_codegen_access, 
                            System.Web.UI.Util.GetCurrentAccountName(), _tempDir)); 
                    }
                } 
            }
        }

        private void InitializeHealthMonitoring() { 
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
            ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel; 
            int deadLockInterval = (int)pmConfig.ResponseDeadlockInterval.TotalSeconds; 
            int requestQueueLimit = pmConfig.RequestQueueLimit;
            Debug.Trace("HealthMonitor", "Initalizing: ResponseDeadlockInterval=" + deadLockInterval); 
            UnsafeNativeMethods.InitializeHealthMonitor(deadLockInterval, requestQueueLimit);
#endif // !FEATURE_PAL
        }
 
        private static void InitHttpConfiguration() {
            if (!_theRuntime._configInited) { 
                _theRuntime._configInited = true; 

                HttpConfigurationSystem.EnsureInit(null, true, true); 

                // whenever possible report errors in the user's culture (from machine.config)
                // Note: this thread's culture is saved/restored during FirstRequestInit, so this is safe
                // see ASURT 81655 

                GlobalizationSection globConfig = RuntimeConfig.GetAppLKGConfig().Globalization; 
                if (globConfig != null) { 
                    if (!String.IsNullOrEmpty(globConfig.Culture) &&
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.Culture, "auto")) 
                        Thread.CurrentThread.CurrentCulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.Culture);

                    if (!String.IsNullOrEmpty(globConfig.UICulture) &&
                        !StringUtil.StringStartsWithIgnoreCase(globConfig.UICulture, "auto")) 
                        Thread.CurrentThread.CurrentUICulture = HttpServerUtility.CreateReadOnlyCultureInfo(globConfig.UICulture);
                } 
 
                // check for errors in  section
                RuntimeConfig appConfig = RuntimeConfig.GetAppConfig(); 
                object section = appConfig.ProcessModel;
                // check for errors in  section
                section = appConfig.HostingEnvironment;
            } 
        }
 
        private void InitHeaderEncoding() { 
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppConfig().HttpRuntime;
            _enableHeaderChecking = runtimeConfig.EnableHeaderChecking; 
        }

        private static void SetAutogenKeys() {
#if !FEATURE_PAL // FEATURE_PAL does not enable cryptography 
            byte[] bKeysRandom = new byte[s_autogenKeys.Length];
            byte[] bKeysStored = new byte[s_autogenKeys.Length]; 
            bool fGetStoredKeys = false; 
            RNGCryptoServiceProvider randgen = new RNGCryptoServiceProvider();
 
            // Gernerate random keys
            randgen.GetBytes(bKeysRandom);

            // If getting stored keys via WorkerRequest object failed, get it directly 
            if (!fGetStoredKeys)
                fGetStoredKeys = (UnsafeNativeMethods.EcbCallISAPI(IntPtr.Zero, UnsafeNativeMethods.CallISAPIFunc.GetAutogenKeys, 
                                                                   bKeysRandom, bKeysRandom.Length, bKeysStored, bKeysStored.Length) == 1); 

            // If we managed to get stored keys, copy them in; else use random keys 
            if (fGetStoredKeys)
                Buffer.BlockCopy(bKeysStored, 0, s_autogenKeys, 0, s_autogenKeys.Length);
            else
                Buffer.BlockCopy(bKeysRandom, 0, s_autogenKeys, 0, s_autogenKeys.Length); 
#endif // !FEATURE_PAL
        } 
 
        internal static void IncrementActivePipelineCount() {
            Interlocked.Increment(ref _theRuntime._activeRequestCount); 
            HostingEnvironment.IncrementBusyCount();
        }

        internal static void DecrementActivePipelineCount() { 
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _theRuntime._activeRequestCount); 
        } 

        internal static bool UseIntegratedPipeline { 
            get {
                return _useIntegratedPipeline;
            }
            set { 
                _useIntegratedPipeline = value;
            } 
        } 

 
        /*
         * Process one step of the integrated pipeline
         *
         */ 

        internal static RequestNotificationStatus ProcessRequestNotification(IIS7WorkerRequest wr, HttpContext context) 
        { 
            return _theRuntime.ProcessRequestNotificationPrivate(wr, context);
        } 

        private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) {
            RequestNotificationStatus status = RequestNotificationStatus.Pending;
            try { 
                // setup the HttpContext for this event/module combo
                context.CurrentModuleIndex = UnsafeIISMethods.MgdGetCurrentModuleIndex(wr.RequestContext); 
                context.IsPostNotification = UnsafeIISMethods.MgdIsCurrentNotificationPost(wr.RequestContext); 
                context.CurrentNotification = (RequestNotification)UnsafeIISMethods.MgdGetCurrentNotification(wr.RequestContext);
#if DBG 
                Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: notification=" + context.CurrentNotification.ToString()
                            + ", isPost=" + context.IsPostNotification
                            + ", moduleIndex=" + context.CurrentModuleIndex);
#endif 

                IHttpHandler handler = null; 
                if (context.NeedToInitializeApp()) { 
                    // First request initialization
                    try { 
                        EnsureFirstRequestInit(context);
                    }
                    catch {
                        // If we are handling a DEBUG request, ignore the FirstRequestInit exception. 
                        // This allows the HttpDebugHandler to execute, and lets the debugger attach to
                        // the process (VSWhidbey 358135) 
                        if (!context.Request.IsDebuggingRequest) { 
                            throw;
                        } 
                    }

                    context.Response.InitResponseWriter();
                    handler = HttpApplicationFactory.GetApplicationInstance(context); 
                    if (handler == null)
                        throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 
 
                    if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, handler.GetType().FullName, "Start");
 
                    HttpApplication app = handler as HttpApplication;
                    if (app != null) {
                        // associate the context with an application instance
                        app.AssignContext(context); 
                    }
                } 
 
                // this may throw, and should be called after app initialization
                wr.SynchronizeVariables(context); 

                if (context.ApplicationInstance != null) {
                    // process request
                    IAsyncResult ar = context.ApplicationInstance.BeginProcessRequestNotification(context, _requestNotificationCompletionCallback); 

                    if (ar.CompletedSynchronously) { 
                        status = RequestNotificationStatus.Continue; 
                    }
                } 
                else if (handler != null) {
                    // HttpDebugHandler is processed here
                    handler.ProcessRequest(context);
                    status = RequestNotificationStatus.FinishRequest; 
                }
                else { 
                    status = RequestNotificationStatus.Continue; 
                }
            } 
            catch (Exception e) {
                status = RequestNotificationStatus.FinishRequest;
                context.Response.InitResponseWriter();
                // errors are handled in HttpRuntime::FinishRequestNotification 
                context.AddError(e);
            } 
 
            if (status != RequestNotificationStatus.Pending) {
                // we completed synchronously 
                FinishRequestNotification(wr, context, ref status);
            }

#if DBG 
            Debug.Trace("PipelineRuntime", "HttpRuntime::ProcessRequestNotificationPrivate: status=" + status.ToString());
#endif 
 
            return status;
        } 

        private void FinishRequestNotification(IIS7WorkerRequest wr, HttpContext context, ref RequestNotificationStatus status) {

            Debug.Assert(status != RequestNotificationStatus.Pending, "status != RequestNotificationStatus.Pending"); 

            HttpApplication app = context.ApplicationInstance; 
 
            if (context.NotificationContext.RequestCompleted) {
                status = RequestNotificationStatus.FinishRequest; 
            }

            // check if the app offline or whether an error has occurred, and report the condition
            context.ReportRuntimeErrorIfExists(ref status); 

            // we do not return FinishRequest for LogRequest or EndRequest 
            if (status == RequestNotificationStatus.FinishRequest 
                && (context.CurrentNotification == RequestNotification.LogRequest
                    || context.CurrentNotification == RequestNotification.EndRequest)) { 
                status = RequestNotificationStatus.Continue;
            }

            IntPtr requestContext = wr.RequestContext; 
            bool sendHeaders = UnsafeIISMethods.MgdIsLastNotification(requestContext, status);
            try { 
                context.Response.UpdateNativeResponse(sendHeaders); 
            }
            catch(Exception e) { 
                // if we catch an exception here then
                // i) clear cached response body bytes on the worker request
                // ii) clear the managed headers, the IIS native headers, the mangaged httpwriter response buffers, and the native IIS response buffers
                // iii) attempt to format the exception and write it to the response 
                wr.UnlockCachedResponseBytes();
                context.AddError(e); 
                context.ReportRuntimeErrorIfExists(ref status); 
                context.Response.UpdateNativeResponse(sendHeaders);
            } 

            if (sendHeaders) {
                context.FinishPipelineRequest();
            } 

            // Perf optimization: dispose managed context if possible (no need to try if status is pending) 
            if (status != RequestNotificationStatus.Pending) { 
                PipelineRuntime.DisposeHandler(context, requestContext, status);
            } 
        }

        internal static void FinishPipelineRequest(HttpContext context) {
            // Remember that first request is done 
            _theRuntime._firstRequestCompleted = true;
            context.Request.Dispose(); 
            context.Response.Dispose(); 
            HttpApplication app = context.ApplicationInstance;
            if(null != app) { 
                HttpApplication.ThreadContext threadContext = context.IndicateCompletionContext;
                if (threadContext != null) {
                    if (!threadContext.HasLeaveBeenCalled) {
                        lock (threadContext) { 
                            if (!threadContext.HasLeaveBeenCalled) {
                                threadContext.Leave(); 
                                context.IndicateCompletionContext = null; 
                                context.InIndicateCompletion = false;
                            } 
                        }
                    }
                }
                app.ReleaseAppInstance(); 
            }
 
            SetExecutionTimePerformanceCounter(context); 
            UpdatePerfCounters(context.Response.StatusCode);
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest); 

            // In case of a HostingInit() error, app domain should not stick around
            if (HostingInitFailed) {
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error"); 
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error");
            } 
        } 

 
        /*
         * Process one request
         */
        private void ProcessRequestInternal(HttpWorkerRequest wr) { 
            // Construct the Context on HttpWorkerRequest, hook everything together
            HttpContext context; 
 
            try {
                context = new HttpContext(wr, false /* initResponseWriter */); 
            }
            catch {
                // If we fail to create the context for any reason, send back a 400 to make sure
                // the request is correctly closed (relates to VSUQFE3962) 
                wr.SendStatus(400, "Bad Request");
                wr.SendKnownResponseHeader(HttpWorkerRequest.HeaderContentType, "text/html; charset=utf-8"); 
                byte[] body = Encoding.ASCII.GetBytes("Bad Request"); 
                wr.SendResponseFromMemory(body, body.Length);
                wr.FlushResponse(true); 
                wr.EndOfRequest();
                return;
            }
 
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context);
 
            // Count active requests 
            Interlocked.Increment(ref _activeRequestCount);
            HostingEnvironment.IncrementBusyCount(); 

            try {
                // First request initialization
                try { 
                    EnsureFirstRequestInit(context);
                } 
                catch { 
                    // If we are handling a DEBUG request, ignore the FirstRequestInit exception.
                    // This allows the HttpDebugHandler to execute, and lets the debugger attach to 
                    // the process (VSWhidbey 358135)
                    if (!context.Request.IsDebuggingRequest) {
                        throw;
                    } 
                }
 
                // Init response writer (after we have config in first request init) 
                // no need for impersonation as it is handled in config system
                context.Response.InitResponseWriter(); 

                // Get application instance
                IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context);
 
                if (app == null)
                    throw new HttpException(SR.GetString(SR.Unable_create_app_object)); 
 
                if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, app.GetType().FullName, "Start");
 
                // Process the request

                if (app is IHttpAsyncHandler) {
                    // asynchronous handler 
                    IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app;
                    context.AsyncAppHandler = asyncHandler; 
                    asyncHandler.BeginProcessRequest(context, _handlerCompletionCallback, context); 
                }
                else { 
                    // synchronous handler
                    app.ProcessRequest(context);
                    FinishRequest(context.WorkerRequest, context, null);
                } 
            }
            catch (Exception e) { 
                context.Response.InitResponseWriter(); 
                FinishRequest(wr, context, e);
            } 
        }

        private void RejectRequestInternal(HttpWorkerRequest wr, bool silent) {
            // Construct the Context on HttpWorkerRequest, hook everything together 
            HttpContext context = new HttpContext(wr, false /* initResponseWriter */);
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); 
 
            // Count active requests
            Interlocked.Increment(ref _activeRequestCount); 
            HostingEnvironment.IncrementBusyCount();

            if (silent) {
                context.Response.InitResponseWriter(); 
                FinishRequest(wr, context, null);
            } 
            else { 
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.REQUESTS_REJECTED);
                PerfCounters.IncrementCounter(AppPerfCounter.APP_REQUESTS_REJECTED); 
                try {
                    throw new HttpException(503, SR.GetString(SR.Server_too_busy));
                }
                catch (Exception e) { 
                    context.Response.InitResponseWriter();
                    FinishRequest(wr, context, e); 
                } 
            }
        } 


        /*
         * Finish processing request, sync or async 
         */
        private void FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) { 
            HttpResponse response = context.Response; 

            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_END_HANDLER, context.WorkerRequest); 

            SetExecutionTimePerformanceCounter(context);

            // Flush in case of no error 
            if (e == null) {
                // impersonate around PreSendHeaders / PreSendContent 
                using (new ClientImpersonationContext(context, false)) { 
                    try {
                        // this sends the actual content in most cases 
                        response.FinalFlushAtTheEndOfRequestProcessing();
                    }
                    catch (Exception eFlush) {
                        e = eFlush; 
                    }
                } 
            } 

            // Report error if any 
            if (e != null) {
                if (_appOfflineMessage != null) {
                    try {
                        response.StatusCode = 404; 
                        response.OutputStream.Write(_appOfflineMessage, 0, _appOfflineMessage.Length);
                        response.FinalFlushAtTheEndOfRequestProcessing(); 
                    } 
                    catch {
                    } 
                }
                else {
                    using (new HttpContextWrapper(context)) {
                        // when application is on UNC share the code below must 
                        // be run while impersonating the token given by IIS
                        using (new ApplicationImpersonationContext()) { 
                            try { 
                                try {
                                    // try to report error in a way that could possibly throw (a config exception) 
                                    response.ReportRuntimeError(e, true /*canThrow*/, false);
                                }
                                catch (Exception eReport) {
                                    // report the config error in a way that would not throw 
                                    response.ReportRuntimeError(eReport, false /*canThrow*/, false);
                                } 
 
                                response.FinalFlushAtTheEndOfRequestProcessing();
                            } 
                            catch {
                            }
                        }
                    } 
                }
            } 
 
            // Remember that first request is done
            _firstRequestCompleted = true; 


            // In case we reporting HostingInit() error, app domain should not stick around
            if (_hostingInitFailed) { 
                Debug.Trace("AppDomainFactory", "Shutting down appdomain because of HostingInit error");
                ShutdownAppDomain(ApplicationShutdownReason.HostingEnvironment, "HostingInit error"); 
            } 

            // Check status code and increment proper counter 
            // If it's an error status code (i.e. 400 or higher), increment the proper perf counters
            int statusCode = response.StatusCode;
            UpdatePerfCounters(statusCode);
 
            context.FinishRequestForCachedPathData(statusCode);
 
            wr.EndOfRequest(); 

            // Count active requests 
            HostingEnvironment.DecrementBusyCount();
            Interlocked.Decrement(ref _activeRequestCount);

            // Schedule more work if some requests are queued 
            if (_requestQueue != null)
                _requestQueue.ScheduleMoreWorkIfNeeded(); 
        } 

        // 
        // Make sure shutdown happens only once
        //

        private bool InitiateShutdownOnce() { 
            if (_shutdownInProgress)
                return false; 
 
            lock (this) {
                if (_shutdownInProgress) 
                    return false;
                _shutdownInProgress = true;
            }
 
            return true;
        } 
 
        //
        // Shutdown this and restart new app domain 
        //

        private void ReleaseResourcesAndUnloadAppDomain(Object state /*not used*/) {
            Debug.Trace("AppDomainFactory", "ReleaseResourcesAndUnloadAppDomain, Id=" + _appDomainAppId 
                        + " DomainId = " + _appDomainId
                        + " Stack = " + Environment.StackTrace ); 
 
            try {
                PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.APPLICATION_RESTARTS); 
            }
            catch {
            }
 
            // Release all resources
            try { 
                Dispose(); 
            }
            catch { 
            }

            Thread.Sleep(250);
 
            AddAppDomainTraceMessage("before Unload");
 
            for (; ; ) { 
                try {
                    AppDomain.Unload(Thread.GetDomain()); 
                }
                catch (CannotUnloadAppDomainException) {
                    Debug.Assert(false);
                } 
                catch (Exception e) {
                    Debug.Trace("AppDomainFactory", "AppDomain.Unload exception: " + e + "; Id=" + _appDomainAppId); 
                    AddAppDomainTraceMessage("Unload Exception: " + e); 
                    throw;
                } 
            }
        }

        private static void SetExecutionTimePerformanceCounter(HttpContext context) { 
            // Set the Request Execution time perf counter
            TimeSpan elapsed = DateTime.UtcNow.Subtract(context.WorkerRequest.GetStartTime()); 
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond; 

            if (milli > Int32.MaxValue) 
                milli = Int32.MaxValue;

            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_EXECUTION_TIME, (int)milli);
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_EXEC_TIME, (int)milli); 
        }
 
        private static void UpdatePerfCounters(int statusCode) { 
            if (400 <= statusCode) {
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED); 
                switch (statusCode) {
                    case 401: // Not authorized
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_AUTHORIZED);
                        break; 
                    case 404: // Not found
                    case 414: // Not found 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND); 
                        break;
                } 
            }
            else {
                // If status code is not in the 400-599 range (i.e. 200-299 success or 300-399 redirection),
                // count it as a successful request. 
                PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_SUCCEDED);
            } 
        } 

        private void WaitForRequestsToFinish(int waitTimeoutMs) { 
            DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(waitTimeoutMs);

            for (; ; ) {
                if (_activeRequestCount == 0 && (_requestQueue == null || _requestQueue.IsEmpty)) 
                    break;
 
                Thread.Sleep(250); 

                // only apply timeout if a managed debugger is not attached 
                if (!System.Diagnostics.Debugger.IsAttached && DateTime.UtcNow > waitLimit) {
                    break; // give it up
                }
            } 
        }
 
        /* 
         * Cleanup of all unmananged state
         */ 
        private void Dispose() {
            // get shutdown timeout from config
            int drainTimeoutSec = HttpRuntimeSection.DefaultShutdownTimeout;
            HttpRuntimeSection runtimeConfig = RuntimeConfig.GetAppLKGConfig().HttpRuntime; 
            if (runtimeConfig != null) {
                drainTimeoutSec = (int)runtimeConfig.ShutdownTimeout.TotalSeconds; 
            } 

            // before aborting compilation give time to drain (new requests are no longer coming at this point) 
            WaitForRequestsToFinish(drainTimeoutSec * 1000);

            // reject remaining queued requests
            if (_requestQueue != null) 
                _requestQueue.Drain();
 
            // give it a little more time to drain 
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6);
 

            // wait for pending async io to complete,  prior to aborting requests
            // this isn't necessary for IIS 7, where the async sends are always done
            // from native code with native buffers 
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo();
 
            // For IIS7 integrated pipeline, wait until GL_APPLICATION_STOP fires and 
            // there are no active calls to IndicateCompletion before unloading the AppDomain
            if (HttpRuntime.UseIntegratedPipeline) { 
                PipelineRuntime.WaitForRequestsToDrain();
            }

#if ORCAS 
            // Kill the HttpDataStore cleanup thread and dispose the storage provider
            if (_httpDataStorageCleanup != null) { 
                _httpDataStorageCleanup.Stop(); 
            }
 
            if (_httpDataStorageProvider != null) {
                _httpDataStorageProvider.Dispose();
            }
#endif 

            // Dispose AppDomainShutdownTimer 
            DisposeAppDomainShutdownTimer(); 

            // kill all remaining requests (and the timeout timer) 
            _timeoutManager.Stop();

            // give it a little more time to drain
            WaitForRequestsToFinish((drainTimeoutSec * 1000) / 6); 

#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features 
            // double check for pending async io 
            System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.WaitForPendingAsyncIo();
 
            // stop sqlcachedependency polling
            SqlCacheDependencyManager.Dispose((drainTimeoutSec * 1000) / 2);
#endif // !FEATURE_PAL
            // cleanup cache (this ends all sessions) 
            if (_cacheInternal != null) {
                _cacheInternal.Dispose(); 
            } 
#if SITECOUNTERS
 
            // cleanup siteCounters (this flushes all counter data)
            if (_siteCounters != null) {
                _siteCounters.Dispose();
            } 
#endif
            // app on end, cleanup app instances 
            HttpApplicationFactory.EndApplication();  // call app_onEnd 

            // stop file changes monitor 
            _fcm.Stop();

            // stop health monitoring timer
            HealthMonitoringManager.Shutdown(); 
        }
 
        /* 
         * Async completion of IIS7 pipeline (unlike OnHandlerCompletion, this may fire more than once).
         */ 
        private void OnRequestNotificationCompletion(IAsyncResult ar) {
            try {
                OnRequestNotificationCompletionHelper(ar);
            } 
            catch(Exception e) {
                ApplicationManager.RecordFatalException(e); 
                throw; 
            }
        } 

        private void OnRequestNotificationCompletionHelper(IAsyncResult ar) {
            if (ar.CompletedSynchronously) {
                Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed synchronously"); 
                return;
            } 
 
            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion: completed asynchronously");
 
            RequestNotificationStatus status = RequestNotificationStatus.Continue;
            HttpContext context = (HttpContext) ar.AsyncState;
            IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;
 
            try {
                context.ApplicationInstance.EndProcessRequestNotification(ar); 
            } 
            catch (Exception e) {
                status = RequestNotificationStatus.FinishRequest; 
                context.AddError(e);
            }

            // RequestContext is set to null if this is the last notification, so we need to save it 
            // for the call to PostCompletion
            IntPtr requestContext = wr.RequestContext; 
 
            FinishRequestNotification(wr, context, ref status);
 
            // set the notification context to null since we are exiting this notification
            context.NotificationContext = null;

            // Indicate completion to IIS, so that it can resume 
            // request processing on an IIS thread
            Debug.Trace("PipelineRuntime", "OnRequestNotificationCompletion(" + status + ")"); 
            int result = UnsafeIISMethods.MgdPostCompletion(requestContext, status); 
            Misc.ThrowIfFailedHr(result);
        } 

        /*
         * Async completion of managed pipeline (called at most one time).
         */ 
        private void OnHandlerCompletion(IAsyncResult ar) {
            HttpContext context = (HttpContext)ar.AsyncState; 
 
            try {
                context.AsyncAppHandler.EndProcessRequest(ar); 
            }
            catch (Exception e) {
                context.AddError(e);
            } 
            finally {
                // no longer keep AsyncAppHandler poiting to the application 
                // is only needed to call EndProcessRequest 
                context.AsyncAppHandler = null;
            } 

            FinishRequest(context.WorkerRequest, context, context.Error);
        }
 
        /*
         * Notification from worker request that it is done writing from buffer 
         * so that the buffers can be recycled 
         */
        private void EndOfSendCallback(HttpWorkerRequest wr, Object arg) { 
            Debug.Trace("PipelineRuntime", "HttpRuntime.EndOfSendCallback");
            HttpContext context = (HttpContext)arg;
            context.Request.Dispose();
            context.Response.Dispose(); 
        }
 
        /* 
         * Notification when something in the bin directory changed
         */ 
        private void OnCriticalDirectoryChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of bin dir change or directory rename." +
                " FileName=" + e.FileName + " Action=" + e.Action); 

            ApplicationShutdownReason reason = ApplicationShutdownReason.None; 
            string directoryName = new DirectoryInfo(e.FileName).Name; 

            string message = directoryName + " dir change or directory rename"; 

            if (StringUtil.EqualsIgnoreCase(directoryName, CodeDirectoryName)) {
                reason = ApplicationShutdownReason.CodeDirChangeOrDirectoryRename;
            } 
            else if (StringUtil.EqualsIgnoreCase(directoryName, ResourcesDirectoryName)) {
                reason = ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename; 
            } 
            else if (StringUtil.EqualsIgnoreCase(directoryName, BrowsersDirectoryName)) {
                reason = ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename; 
            }
            else if (StringUtil.EqualsIgnoreCase(directoryName, BinDirectoryName)) {
                reason = ApplicationShutdownReason.BinDirChangeOrDirectoryRename;
            } 

            if (e.Action == FileAction.Added) { 
                // Make sure HttpRuntime does not ignore the appdomain shutdown if a file is added (VSWhidbey 363481) 
                HttpRuntime.SetUserForcedShutdown();
 
                Debug.Trace("AppDomainFactorySpecial", "Call SetUserForcedShutdown: FileName=" + e.FileName + "; now=" + DateTime.Now);
            }

            ShutdownAppDomain(reason, message); 
        }
 
        /** 
         * Coalesce file change notifications to minimize sharing violations and AppDomain restarts (ASURT 147492)
         */ 
        private void CoalesceNotifications() {
            int waitChangeNotification = HttpRuntimeSection.DefaultWaitChangeNotification;
            int maxWaitChangeNotification = HttpRuntimeSection.DefaultMaxWaitChangeNotification;
            try { 
                HttpRuntimeSection config = RuntimeConfig.GetAppLKGConfig().HttpRuntime;
                if (config != null) { 
                    waitChangeNotification = config.WaitChangeNotification; 
                    maxWaitChangeNotification = config.MaxWaitChangeNotification;
                } 
            }
            catch {
            }
 
            if (waitChangeNotification == 0 || maxWaitChangeNotification == 0)
                return; 
 
            DateTime maxWait = DateTime.UtcNow.AddSeconds(maxWaitChangeNotification);
            // Coalesce file change notifications 
            try {
                while (DateTime.UtcNow < maxWait) {
                    if (DateTime.UtcNow > LastShutdownAttemptTime.AddSeconds(waitChangeNotification))
                        break; 

                    Thread.Sleep(250); 
                } 
            }
            catch { 
            }
        }

        // appdomain shutdown eventhandler 
        internal static event BuildManagerHostUnloadEventHandler AppDomainShutdown;
 
        internal static void OnAppDomainShutdown(BuildManagerHostUnloadEventArgs e) { 
            if (AppDomainShutdown != null) {
                AppDomainShutdown(_theRuntime, e); 
            }
        }

        internal static void SetUserForcedShutdown() { 
            _theRuntime._userForcedShutdown = true;
        } 
 
        /*
         * Shutdown the current app domain 
         */
        internal static bool ShutdownAppDomain(ApplicationShutdownReason reason, string message) {
            return ShutdownAppDomainWithStackTrace(reason, message, null /*stackTrace*/);
        } 

        /* 
         * Shutdown the current app domain with a stack trace.  This is useful for callers that are running 
         * on a QUWI callback, and wouldn't provide a meaningful stack trace by default.
         */ 
        internal static bool ShutdownAppDomainWithStackTrace(ApplicationShutdownReason reason, string message, string stackTrace) {
            SetShutdownReason(reason, message);
            return ShutdownAppDomain(stackTrace);
        } 

        private static bool ShutdownAppDomain(string stackTrace) { 
            // Ignore notifications during the processing of the first request (ASURT 100335) 
            if (!_theRuntime._firstRequestCompleted && !_theRuntime._userForcedShutdown) {
                // check the timeout (don't disable notifications forever 
                int delayTimeoutSec = HttpRuntimeSection.DefaultDelayNotificationTimeout;

                try {
                    RuntimeConfig runtimeConfig = RuntimeConfig.GetAppLKGConfig(); 
                    if (runtimeConfig != null) {
                        HttpRuntimeSection runtimeSection = runtimeConfig.HttpRuntime; 
                        if (runtimeSection != null) { 
                            delayTimeoutSec = (int)runtimeSection.DelayNotificationTimeout.TotalSeconds;
 
                            if (DateTime.UtcNow < _theRuntime._firstRequestStartTime.AddSeconds(delayTimeoutSec)) {
                                Debug.Trace("AppDomainFactory", "ShutdownAppDomain IGNORED (1st request is not done yet), Id = " + AppDomainAppIdInternal);
                                return false;
                            } 
                        }
                    } 
                } 
                catch {
                } 
            }

            try {
                _theRuntime.RaiseShutdownWebEventOnce(); 
            }
            catch { 
                // VSWhidbey 444472: if an exception is thrown, we consume it and continue executing the following code. 
            }
 
            // Update last time ShutdownAppDomain was called
            _theRuntime.LastShutdownAttemptTime = DateTime.UtcNow;

            _theRuntime.CoalesceNotifications(); 

            if (!HostingEnvironment.ShutdownInitiated) { 
                // This shutdown is not triggered by hosting environment - let it do the job 
                HostingEnvironment.InitiateShutdown();
                return true; 
            }

            //WOS 1400290: CantUnloadAppDomainException in ISAPI mode, wait until HostingEnvironment.ShutdownThisAppDomainOnce completes
            if (HostingEnvironment.ShutdownInProgress) { 
                return false;
            } 
 
            // Make sure we don't go through shutdown logic many times
            if (!_theRuntime.InitiateShutdownOnce()) 
                return false;

            Debug.Trace("AppDomainFactory", "ShutdownAppDomain, Id = " + AppDomainAppIdInternal + ", ShutdownInProgress=" + ShutdownInProgress
                        + ", ShutdownMessage=" + _theRuntime._shutDownMessage); 

            if (String.IsNullOrEmpty(stackTrace)) { 
                // Instrument to be able to see what's causing a shutdown 
                new EnvironmentPermission(PermissionState.Unrestricted).Assert();
                try { 
                    _theRuntime._shutDownStack = Environment.StackTrace;
                }
                finally {
                    CodeAccessPermission.RevertAssert(); 
                }
            } 
            else { 
                _theRuntime._shutDownStack = stackTrace;
            } 

            // Notify when appdomain is about to shutdown.
            OnAppDomainShutdown(new BuildManagerHostUnloadEventArgs(_theRuntime._shutdownReason));
 
            // unload app domain from another CLR thread
            ThreadPool.QueueUserWorkItem(_theRuntime._appDomainUnloadallback); 
 
            return true;
        } 

        internal static void RecoverFromUnexceptedAppDomainUnload() {
            if (_theRuntime._shutdownInProgress)
                return; 

            // someone unloaded app domain directly - tell unmanaged code 
            Debug.Trace("AppDomainFactory", "Unexpected AppDomainUnload"); 
            _theRuntime._shutdownInProgress = true;
 
            // tell unmanaged code not to dispatch requests to this app domain
            try {
                ISAPIRuntime.RemoveThisAppDomainFromUnmanagedTable();
                PipelineRuntime.RemoveThisAppDomainFromUnmanagedTable(); 
                AddAppDomainTraceMessage("AppDomainRestart");
            } 
            finally { 
                // release all resources
                _theRuntime.Dispose(); 
            }
        }

        /* 
         * Notification when app-level Config changed
         */ 
        internal static void OnConfigChange() { 
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because of config change");
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "CONFIG change"); 
        }

        // Intrumentation to remember the overwhelming file change
        internal static void SetShutdownReason(ApplicationShutdownReason reason, String message) { 
            if (_theRuntime._shutdownReason == ApplicationShutdownReason.None) {
                _theRuntime._shutdownReason = reason; 
            } 

            SetShutdownMessage(message); 
        }

        internal static void SetShutdownMessage(String message) {
            if (message != null) { 
                if (_theRuntime._shutDownMessage == null)
                    _theRuntime._shutDownMessage = message; 
                else 
                    _theRuntime._shutDownMessage += "\r\n" + message;
            } 
        }


        // public method is on HostingEnvironment 
        internal static ApplicationShutdownReason ShutdownReason {
            get { return _theRuntime._shutdownReason; } 
        } 

        // 
        // public static APIs
        //

        /* 
         * Process one request
         */ 
 
        /// 
        ///    The method that drives 
        ///       all ASP.NET web processing execution.
        /// 
        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
        public static void ProcessRequest(HttpWorkerRequest wr) { 
            if (wr == null)
                throw new ArgumentNullException("wr"); 
 
            ProcessRequestNoDemand(wr);
        } 


        internal static void ProcessRequestNoDemand(HttpWorkerRequest wr) {
            RequestQueue rq = _theRuntime._requestQueue; 

            if (rq != null)  // could be null before first request 
                wr = rq.GetRequestToExecute(wr); 

            if (wr != null) { 
                CalculateWaitTimeAndUpdatePerfCounter(wr);
                wr.ResetStartTime();
                ProcessRequestNow(wr);
            } 
        }
 
 
        private static void CalculateWaitTimeAndUpdatePerfCounter(HttpWorkerRequest wr) {
            DateTime begin = wr.GetStartTime(); 

            TimeSpan elapsed = DateTime.UtcNow.Subtract(begin);
            long milli = elapsed.Ticks / TimeSpan.TicksPerMillisecond;
 
            if (milli > Int32.MaxValue)
                milli = Int32.MaxValue; 
 
            PerfCounters.SetGlobalCounter(GlobalPerfCounter.REQUEST_WAIT_TIME, (int)milli);
            PerfCounters.SetCounter(AppPerfCounter.APP_REQUEST_WAIT_TIME, (int)milli); 
        }

        internal static void ProcessRequestNow(HttpWorkerRequest wr) {
            _theRuntime.ProcessRequestInternal(wr); 
        }
 
        internal static void RejectRequestNow(HttpWorkerRequest wr, bool silent) { 
            _theRuntime.RejectRequestInternal(wr, silent);
        } 


        /// 
        ///       Removes all items from the cache and shuts down the runtime. 
        ///    
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        public static void Close() { 
            Debug.Trace("AppDomainFactory", "HttpRuntime.Close, ShutdownInProgress=" + ShutdownInProgress);
            if (_theRuntime.InitiateShutdownOnce()) { 
                SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called");

                if (HostingEnvironment.IsHosted) {
                    // go throw initiate shutdown for hosted scenarios 
                    HostingEnvironment.InitiateShutdown();
                } 
                else { 
                    _theRuntime.Dispose();
                } 
            }
        }

 
        /// 
        ///       Unloads the current app domain. 
        ///     
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
        public static void UnloadAppDomain() { 
            _theRuntime._userForcedShutdown = true;
            ShutdownAppDomain(ApplicationShutdownReason.UnloadAppDomainCalled, "User code called UnloadAppDomain");
        }
 
        private DateTime LastShutdownAttemptTime {
            get { 
                DateTime dt; 
                lock (this) {
                    dt = _lastShutdownAttemptTime; 
                }
                return dt;
            }
            set { 
                lock (this) {
                    _lastShutdownAttemptTime = value; 
                } 
            }
        } 

        internal static Profiler Profile {
            get {
                return _theRuntime._profiler; 
            }
        } 
 
        internal static bool IsTrustLevelInitialized {
            get { 
                return !HostingEnvironment.IsHosted || TrustLevel != null;
            }
        }
 
        internal static NamedPermissionSet NamedPermissionSet {
            get { 
                // Make sure we have already initialized the trust level 
                //
 

                return _theRuntime._namedPermissionSet;
            }
        } 

        [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Unrestricted)] 
        public static NamedPermissionSet GetNamedPermissionSet() { 
            NamedPermissionSet namedPermissionSet = _theRuntime._namedPermissionSet;
            if (namedPermissionSet == null) { 
                return null;
            }
            else {
                return new NamedPermissionSet(namedPermissionSet); 
            }
        } 
 

        internal static bool IsFullTrust { 
            get {
                // Make sure we have already initialized the trust level
                Debug.Assert(IsTrustLevelInitialized);
 
                return (_theRuntime._namedPermissionSet == null);
            } 
        } 

        /* 
         * Check that the current trust level allows access to a virtual path.  Throw if it doesn't,
         */
        internal static void CheckVirtualFilePermission(string virtualPath) {
            string physicalPath = HostingEnvironment.MapPath(virtualPath); 
            CheckFilePermission(physicalPath);
        } 
 
        /*
         * Check that the current trust level allows access to a path.  Throw if it doesn't, 
         */
        internal static void CheckFilePermission(string path) {
            CheckFilePermission(path, false);
        } 

        internal static void CheckFilePermission(string path, bool writePermissions) { 
            if (!HasFilePermission(path, writePermissions)) { 
                throw new HttpException(SR.GetString(SR.Access_denied_to_path, GetSafePath(path)));
            } 
        }

        internal static bool HasFilePermission(string path) {
            return HasFilePermission(path, false); 
        }
 
        internal static bool HasFilePermission(string path, bool writePermissions) { 
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an
            // InitializationException (e.g., necessary to display line info for ConfigurationException). 

            if (TrustLevel == null && InitializationException != null) {
                return true;
            } 

            // Make sure we have already initialized the trust level 
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted, "TrustLevel != null || !HostingEnvironment.IsHosted"); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true;

            bool fAccess = false; 

            // Check that the user has permission to the path 
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = null; 
                try {
                    if (!writePermissions)
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.Read, path);
                    else 
                        askedPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, path);
                } 
                catch { 
                    // This could happen if the path is not absolute
                    return false; 
                }
                fAccess = askedPermission.IsSubsetOf(allowedPermission);
            }
 
            return fAccess;
        } 
 
        internal static bool HasWebPermission(Uri uri) {
 
            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted);

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true; 
 
            bool fAccess = false;
 
            // Check that the user has permission to the URI
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(WebPermission));
            if (allowedPermission != null) {
                IPermission askedPermission = null; 
                try {
                    askedPermission = new WebPermission(NetworkAccess.Connect, uri.ToString()); 
                } 
                catch {
                    return false; 
                }
                fAccess = askedPermission.IsSubsetOf(allowedPermission);
            }
 
            return fAccess;
        } 
 
        internal static bool HasDbPermission(DbProviderFactory factory) {
 
            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted);

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true; 
 
            bool fAccess = false;
 
            // Check that the user has permission to the provider
            CodeAccessPermission askedPermission = factory.CreatePermission(PermissionState.Unrestricted);
            if (askedPermission != null) {
                IPermission allowedPermission = NamedPermissionSet.GetPermission(askedPermission.GetType()); 
                if (allowedPermission != null) {
                    fAccess = askedPermission.IsSubsetOf(allowedPermission); 
                } 
            }
 
            return fAccess;
        }

        internal static bool HasPathDiscoveryPermission(string path) { 
            // WOS #1523618: need to skip this check for HttpResponse.ReportRuntimeError when reporting an
            // InitializationException (e.g., necessary to display line info for ConfigurationException). 
 
            if (TrustLevel == null && InitializationException != null) {
                return true; 
            }

            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted); 

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null) 
                return true;
 
            bool fAccess = false;

            // Check that the user has permission to the path
            IPermission allowedPermission = NamedPermissionSet.GetPermission(typeof(FileIOPermission)); 
            if (allowedPermission != null) {
                IPermission askedPermission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path); 
                fAccess = askedPermission.IsSubsetOf(allowedPermission); 
            }
 
            return fAccess;

        }
 
        internal static bool HasAppPathDiscoveryPermission() {
            return HasPathDiscoveryPermission(HttpRuntime.AppDomainAppPathInternal); 
        } 

        internal static string GetSafePath(string path) { 
            if (String.IsNullOrEmpty(path))
                return path;

            try { 
                if (HasPathDiscoveryPermission(path)) // could throw on bad filenames
                    return path; 
            } 
            catch {
            } 

            return Path.GetFileName(path);
        }
 
        /*
         * Check that the current trust level allows Unmanaged access 
         */ 
        internal static bool HasUnmanagedPermission() {
 
            // Make sure we have already initialized the trust level
            Debug.Assert(TrustLevel != null || !HostingEnvironment.IsHosted);

            // If we don't have a NamedPermissionSet, we're in full trust 
            if (NamedPermissionSet == null)
                return true; 
 
            SecurityPermission securityPermission = (SecurityPermission)NamedPermissionSet.GetPermission(
                typeof(SecurityPermission)); 
            if (securityPermission == null)
                return false;

            return (securityPermission.Flags & SecurityPermissionFlag.UnmanagedCode) != 0; 
        }
 
        internal static bool HasAspNetHostingPermission(AspNetHostingPermissionLevel level) { 

            // Make sure we have already initialized the trust level 
            //


 
            // If we don't have a NamedPermissionSet, we're in full trust
            if (NamedPermissionSet == null) 
                return true; 

            AspNetHostingPermission permission = (AspNetHostingPermission)NamedPermissionSet.GetPermission( 
                typeof(AspNetHostingPermission));
            if (permission == null)
                return false;
 
            return (permission.Level >= level);
        } 
 
        internal static void CheckAspNetHostingPermission(AspNetHostingPermissionLevel level, String errorMessageId) {
            if (!HasAspNetHostingPermission(level)) { 
                throw new HttpException(SR.GetString(errorMessageId));
            }
        }
 
        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, ElementInformation elemInfo, string propertyName) { 
 
            if (!IsTypeAllowedInConfig(t)) {
                if (null != elemInfo) { 
                    PropertyInformation propInfo = elemInfo.Properties[propertyName];

                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName),
                    propInfo.Source, propInfo.LineNumber); 
                }
                else { 
                    throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName)); 
                }
            } 
        }

        // If we're not in full trust, fail if the passed in type doesn't have the APTCA bit
        internal static void FailIfNoAPTCABit(Type t, XmlNode node) { 

            if (!IsTypeAllowedInConfig(t)) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Type_from_untrusted_assembly, t.FullName), 
                    node);
            } 
        }

        private static bool HasAPTCABit(Assembly assembly) {
            Object[] attrs = assembly.GetCustomAttributes( 
                typeof(System.Security.AllowPartiallyTrustedCallersAttribute), /*inherit*/ false);
            return (attrs != null && attrs.Length > 0); 
        } 

        // Check if the type is allowed to be used in config by checking the APTCA bit 
        internal static bool IsTypeAllowedInConfig(Type t) {

            // Allow everything in full trust
            if (HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted)) 
                return true;
 
            Assembly assembly = t.Assembly; 

            // The APTCA bit is only relevant for assemblies living in the GAC, since the rest runs 
            // under partial trust (VSWhidbey 422183)
            if (!assembly.GlobalAssemblyCache)
                return true;
 
            // If it has the APTCA bit, allow it
            if (HttpRuntime.HasAPTCABit(assembly)) 
                return true; 

            // It's a GAC type without APTCA in partial trust scenario: block it 
            return false;
        }

        internal static FileChangesMonitor FileChangesMonitor { 
            get { return _theRuntime._fcm; }
        } 
 
#if ORCAS
        internal static IHttpDataStorageProvider HttpDataStorageProvider { 
            get { return _theRuntime._httpDataStorageProvider;}
        }
#endif
 
        internal static RequestTimeoutManager RequestTimeoutManager {
            get { return _theRuntime._timeoutManager; } 
        } 

 
        /// 
        ///    Provides access to the cache.
        /// 
        public static Cache Cache { 
            get {
 
                if (HttpRuntime.AspInstallDirectoryInternal == null) { 
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                } 

                // In a web app, ReadCacheInternalConfig() is called from HttpRuntime.HostingInit.
                // However, if the cache is used by a non-http app, HttpRuntime.HostingInit won't
                // be called and we need to find a way to call ReadCacheInternalConfig(). 
                // The safe and inexpensive place to call it is when the non-http app accesses the
                // Cache thru HttpRuntime.Cache. 
                // 
                // ReadCacheInternalConfig() protects itself from being read multiple times.
                // 
                Cache cachePublic = _theRuntime._cachePublic;
                if (cachePublic == null) {
                    CacheInternal cacheInternal = CacheInternal;
                    CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache; 
                    cacheInternal.ReadCacheInternalConfig(cacheSection);
                    _theRuntime._cachePublic = cacheInternal.CachePublic; 
                    cachePublic = _theRuntime._cachePublic; 
                }
 
                return cachePublic;
            }
        }
 
        private void CreateCache() {
            lock (this) { 
                if (_cacheInternal == null) { 
                    _cacheInternal = CacheInternal.Create();
                } 
            }
        }

        internal static CacheInternal CacheInternal { 
            get {
                // Note that we only create the cache on first access, 
                // not in HttpRuntime initialization. 
                // This prevents cache timers from running when
                // the cache is not used. 
                CacheInternal cacheInternal = _theRuntime._cacheInternal;
                if (cacheInternal == null) {
                    _theRuntime.CreateCache();
                    cacheInternal = _theRuntime._cacheInternal; 
                }
 
                return cacheInternal; 
            }
        } 
#if SITECOUNTERS
        internal static SiteCounters SiteCounters {
            get { return _theRuntime._siteCounters; }
        } 
#endif
 
        ///  
        ///    [To be supplied.]
        ///  
        public static string AspInstallDirectory {
            get {
                String path = AspInstallDirectoryInternal;
 
                if (path == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion)); 
                } 

                InternalSecurityPermissions.PathDiscovery(path).Demand(); 
                return path;
            }
        }
 
        internal static string AspInstallDirectoryInternal {
            get { return s_installDirectory; } 
        } 

        // 
        // Return the client script virtual path, e.g. "/aspnet_client/system_web/2_0_50217"
        //
        public static string AspClientScriptVirtualPath {
            get { 
                if (_theRuntime._clientScriptVirtualPath == null) {
                    string aspNetVersion = VersionInfo.SystemWebVersion; 
                    string clientScriptVirtualPath = AspNetClientFilesParentVirtualPath + aspNetVersion.Substring(0, aspNetVersion.LastIndexOf('.')).Replace('.', '_'); 

                    _theRuntime._clientScriptVirtualPath = clientScriptVirtualPath; 
                }

                return _theRuntime._clientScriptVirtualPath;
            } 
        }
 
        public static string AspClientScriptPhysicalPath { 
            get {
                String path = AspClientScriptPhysicalPathInternal; 

                if (path == null) {
                    throw new HttpException(SR.GetString(SR.Aspnet_not_installed, VersionInfo.SystemWebVersion));
                } 

                InternalSecurityPermissions.PathDiscovery(path).Demand(); 
                return path; 
            }
        } 

        //
        // Return the client script physical path, e.g. @"c:\windows\microsoft.net\framework\v2.0.50217.0\asp.netclientfiles"
        // 
        internal static string AspClientScriptPhysicalPathInternal {
            get { 
                if (_theRuntime._clientScriptPhysicalPath == null) { 
                    string clientScriptPhysicalPath = System.IO.Path.Combine(AspInstallDirectoryInternal, AspNetClientFilesSubDirectory);
 
                    _theRuntime._clientScriptPhysicalPath = clientScriptPhysicalPath;
                }

                return _theRuntime._clientScriptPhysicalPath; 
            }
        } 
 

        ///  
        ///    [To be supplied.]
        /// 
        public static string ClrInstallDirectory {
            get { 
                String path = ClrInstallDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand(); 
                return path; 
            }
        } 

        internal static string ClrInstallDirectoryInternal {
            get { return HttpConfigurationSystem.MsCorLibDirectory; }
        } 

 
 
        /// 
        ///    [To be supplied.] 
        /// 
        public static string MachineConfigurationDirectory {
            get {
                String path = MachineConfigurationDirectoryInternal; 
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            } 
        }
 
        internal static string MachineConfigurationDirectoryInternal {
            get { return HttpConfigurationSystem.MachineConfigurationDirectory; }
        }
 
        internal static bool IsEngineLoaded {
            get { return s_isEngineLoaded; } 
        } 

 
        //
        //  Static app domain related properties
        //
 

        ///  
        ///    [To be supplied.] 
        /// 
        public static String CodegenDir { 
            get {
                String path = CodegenDirInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand();
                return path; 
            }
        } 
 
        internal static string CodegenDirInternal {
            get { return _theRuntime._codegenDir; } 
        }

        internal static string TempDirInternal {
            get { return _theRuntime._tempDir; } 
        }
 
 
        /// 
        ///    [To be supplied.] 
        /// 
        public static String AppDomainAppId {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)]
            get { 
                return AppDomainAppIdInternal;
            } 
        } 

        internal static string AppDomainAppIdInternal { 
            get { return _theRuntime._appDomainAppId; }
        }

        internal static bool IsAspNetAppDomain { 
            get { return AppDomainAppIdInternal != null; }
        } 
 

 
        /// 
        ///    [To be supplied.]
        /// 
        public static String AppDomainAppPath { 
            get {
                InternalSecurityPermissions.AppPathDiscovery.Demand(); 
                return AppDomainAppPathInternal; 
            }
        } 

        internal static string AppDomainAppPathInternal {
            get { return _theRuntime._appDomainAppPath; }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        public static String AppDomainAppVirtualPath {
            get {
                return VirtualPath.GetVirtualPathStringNoTrailingSlash(_theRuntime._appDomainAppVPath);
            } 
        }
 
        // Save as AppDomainAppVirtualPath, but includes the trailng slash.  We can't change 
        // AppDomainAppVirtualPath since it's public.
        internal static String AppDomainAppVirtualPathString { 
            get {
                return VirtualPath.GetVirtualPathString(_theRuntime._appDomainAppVPath);
            }
        } 

        internal static VirtualPath AppDomainAppVirtualPathObject { 
            get { 
                return _theRuntime._appDomainAppVPath;
            } 
        }

        internal static bool IsPathWithinAppRoot(String path) {
            if (AppDomainIdInternal == null) 
                return true;    // app domain not initialized
 
            return UrlPath.IsEqualOrSubpath(AppDomainAppVirtualPathString, path); 
        }
 

        /// 
        ///    [To be supplied.]
        ///  
        public static String AppDomainId {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.High)] 
            get { 
                return AppDomainIdInternal;
            } 
        }

        internal static string AppDomainIdInternal {
            get { return _theRuntime._appDomainId; } 
        }
 
 

        ///  
        ///    [To be supplied.]
        /// 
        public static String BinDirectory {
            get { 
                String path = BinDirectoryInternal;
                InternalSecurityPermissions.PathDiscovery(path).Demand(); 
                return path; 
            }
        } 

        internal static string BinDirectoryInternal {
            get { return Path.Combine(_theRuntime._appDomainAppPath, BinDirectoryName) + Path.DirectorySeparatorChar; }
 
        }
 
        internal static VirtualPath CodeDirectoryVirtualPath { 
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(CodeDirectoryName); }
        } 

        internal static VirtualPath ResourcesDirectoryVirtualPath {
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(ResourcesDirectoryName); }
        } 

        internal static VirtualPath WebRefDirectoryVirtualPath { 
            get { return _theRuntime._appDomainAppVPath.SimpleCombineWithDir(WebRefDirectoryName); } 
        }
 

        /// 
        ///    [To be supplied.]
        ///  
        public static bool IsOnUNCShare {
            [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Low)] 
            get { 
                return IsOnUNCShareInternal;
            } 
        }

        internal static bool IsOnUNCShareInternal {
            get { return _theRuntime._isOnUNCShare; } 
        }
 
 
        //
        //  Static helper to retrieve app domain values 
        //

        private static String GetAppDomainString(String key) {
            Object x = Thread.GetDomain().GetData(key); 

            return x as String; 
        } 

        internal static void AddAppDomainTraceMessage(String message) { 
            const String appDomainTraceKey = "ASP.NET Domain Trace";
            AppDomain d = Thread.GetDomain();
            String m = d.GetData(appDomainTraceKey) as String;
            d.SetData(appDomainTraceKey, (m != null) ? m + " ... " + message : message); 
        }
 
 
        //
        //  Flags 
        //

        internal static bool DebuggingEnabled {
            get { return _theRuntime._debuggingEnabled; } 
        }
 
        internal static bool ConfigInited { 
            get { return _theRuntime._configInited; }
        } 

        internal static bool FusionInited {
            get { return _theRuntime._fusionInited; }
        } 

        internal static bool ApartmentThreading { 
            get { return _theRuntime._apartmentThreading; } 
        }
 
        internal static bool ShutdownInProgress {
            get { return _theRuntime._shutdownInProgress; }
        }
 
        internal static string TrustLevel {
            get { return _theRuntime._trustLevel; } 
        } 

        internal static string WpUserId { 
            get { return _theRuntime._wpUserId; }
        }

 
        private void SetTrustLevel(TrustSection trustSection, SecurityPolicySection securityPolicySection) {
            if (trustSection == null || String.IsNullOrEmpty(trustSection.Level)) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Config_section_not_present, "trust")); 
            }
 
            // Use a temporary variable, since we use the field as a signal that the trust has really
            // been set, which is not the case until later in this method.
            string trustLevel = trustSection.Level;
 
            if (trustSection.Level == "Full") {
                _trustLevel = trustLevel; 
                return; 
            }
 
            if (securityPolicySection == null || securityPolicySection.TrustLevels[trustSection.Level] == null) {
                throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level), String.Empty, 0);
                //             Do not give out configuration information since we don't know what trust level we are
                //             supposed to be running at.  If the information below is added to the error it might expose 
                //             part of the config file that the users does not have permissions to see. VS261145
                //            ,trustSection.ElementInformation.Properties["level"].Source, 
                //            trustSection.ElementInformation.Properties["level"].LineNumber); 
            }
            String file = (String)securityPolicySection.TrustLevels[trustSection.Level].PolicyFileExpanded; 
            if (file == null || !FileUtil.FileExists(file)) {
                //if HttpContext.Current.IsCustomErrorEnabled
                throw new HttpException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level));
                //else 
                //    throw new ConfigurationErrorsException(SR.GetString(SR.Unable_to_get_policy_file, trustSection.Level),
                //        trustSection.Filename, trustSection.LineNumber); 
            } 

            bool foundGacToken = false; 
            PolicyLevel policyLevel = CreatePolicyLevel(file, AppDomainAppPathInternal, CodegenDirInternal, trustSection.OriginUrl, out foundGacToken);

            // see if the policy file contained a v1.x UrlMembershipCondition containing
            // a GAC token.  If so, let's upgrade it by adding a code group granting 
            // full trust to code from the GAC
            if (foundGacToken) { 
                // walk the code groups at the app domain level and look for one that grants 
                // access to the GAC with an UrlMembershipCondition.
                CodeGroup rootGroup = policyLevel.RootCodeGroup; 
                bool foundGacCondition = false;
                foreach (CodeGroup childGroup in rootGroup.Children) {
                    if (childGroup.MembershipCondition is GacMembershipCondition) {
                        foundGacCondition = true; 

                        // if we found the GAC token and also have the GacMembershipCondition 
                        // the policy file needs to be upgraded to just include the GacMembershipCondition 
                        Debug.Assert(!foundGacCondition);
                        break; 
                    }
                }

                // add one as a child of the toplevel group after 
                // some sanity checking to make sure it's an ASP.NET policy file
                // which always begins with a FirstMatchCodeGroup granting nothing 
                // this might not upgrade some custom policy files 
                if (!foundGacCondition) {
                    if (rootGroup is FirstMatchCodeGroup) { 
                        FirstMatchCodeGroup firstMatch = (FirstMatchCodeGroup)rootGroup;
                        if (firstMatch.MembershipCondition is AllMembershipCondition &&
                           firstMatch.PermissionSetName == "Nothing") {
                            PermissionSet fullTrust = new PermissionSet(PermissionState.Unrestricted); 

                            CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(), 
                                                                    new PolicyStatement(fullTrust)); 

 
                            // now, walk the current groups and insert our new group
                            // immediately before the old Gac group
                            // we'll need to use heuristics for this:
                            // it will be an UrlMembershipCondition group with full trust 
                            CodeGroup newRoot = new FirstMatchCodeGroup(rootGroup.MembershipCondition, rootGroup.PolicyStatement);
                            foreach (CodeGroup childGroup in rootGroup.Children) { 
 
                                // is this the target old $Gac$ group?
                                // insert our new GacMembershipCondition group ahead of it 
                                if ((childGroup is UnionCodeGroup) &&
                                   (childGroup.MembershipCondition is UrlMembershipCondition) &&
                                   childGroup.PolicyStatement.PermissionSet.IsUnrestricted()) {
                                    if (null != gacGroup) { 
                                        newRoot.AddChild(gacGroup);
                                        gacGroup = null; 
                                    } 
                                }
 
                                // append this group to the root group
                                // AddChild itself does a deep Copy to get any
                                // child groups so we don't need one here
                                newRoot.AddChild(childGroup); 
                            }
 
                            policyLevel.RootCodeGroup = newRoot; 
                            //Debug.Trace("internal", "PolicyLevel: " + policyLevel.ToXml());
                        } 
                    }
                }
            }
 

            AppDomain.CurrentDomain.SetAppDomainPolicy(policyLevel); 
            _namedPermissionSet = policyLevel.GetNamedPermissionSet("ASP.Net"); 

            _trustLevel = trustLevel; 

            _fcm.StartMonitoringFile(file, new FileChangeEventHandler(this.OnSecurityPolicyFileChange));
        }
 
        private static PolicyLevel CreatePolicyLevel(String configFile, String appDir, String binDir, String strOriginUrl, out bool foundGacToken) {
            // Read in the config file to a string. 
            FileStream file = new FileStream(configFile, FileMode.Open, FileAccess.Read); 
            StreamReader reader = new StreamReader(file, Encoding.UTF8);
            String strFileData = reader.ReadToEnd(); 

            reader.Close();

            appDir = FileUtil.RemoveTrailingDirectoryBackSlash(appDir); 
            binDir = FileUtil.RemoveTrailingDirectoryBackSlash(binDir);
 
            strFileData = strFileData.Replace("$AppDir$", appDir); 
            strFileData = strFileData.Replace("$AppDirUrl$", MakeFileUrl(appDir));
            strFileData = strFileData.Replace("$CodeGen$", MakeFileUrl(binDir)); 
            if (strOriginUrl == null)
                strOriginUrl = String.Empty;
            strFileData = strFileData.Replace("$OriginHost$", strOriginUrl);
 
            // see if the file contains a GAC token
            // if so, do the replacement and record the 
            // fact so that we later add a GacMembershipCondition 
            // codegroup to the PolicyLevel
            int ndx = strFileData.IndexOf("$Gac$", StringComparison.Ordinal); 
            if (ndx != -1) {
                string gacLocation = GetGacLocation();
                if (gacLocation != null)
                    gacLocation = MakeFileUrl(gacLocation); 
                if (gacLocation == null)
                    gacLocation = String.Empty; 
 
                strFileData = strFileData.Replace("$Gac$", gacLocation);
                foundGacToken = true; 
            }
            else {
                foundGacToken = false;
            } 

            return SecurityManager.LoadPolicyLevelFromString(strFileData, PolicyLevelType.AppDomain); 
        } 

        /* 
         * Notification when something in the code-access security policy file changed
         */
        private void OnSecurityPolicyFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because code-access security policy file changed");
            ShutdownAppDomain(ApplicationShutdownReason.ChangeInSecurityPolicyFile, 
                                "Change in code-access security policy file"); 
        }
 

        // notification when app_offline.htm file changed or created
        private void OnAppOfflineFileChange(Object sender, FileChangeEvent e) {
            // shutdown the app domain 
            Debug.Trace("AppOffline", AppOfflineFileName + " changed - shutting down the app domain");
            Debug.Trace("AppDomainFactory", "Shutting down appdomain because " + AppOfflineFileName + " file changed"); 
            // WOS 1948399: set _userForcedShutdown to avoid DelayNotificationTimeout, since first request has not completed yet in integrated mode; 
            SetUserForcedShutdown();
            ShutdownAppDomain(ApplicationShutdownReason.ConfigurationChange, "Change in " + AppOfflineFileName); 
        }

        private static String MakeFileUrl(String path) {
            Uri uri = new Uri(path); 
            return uri.ToString();
        } 
 
        private static String GetGacLocation() {
 
            StringBuilder buf = new StringBuilder(262);
            int iSize = 260;

            // 

            if (UnsafeNativeMethods.GetCachePath(2, buf, ref iSize) >= 0) 
                return buf.ToString(); 
            throw new HttpException(SR.GetString(SR.GetGacLocaltion_failed));
        } 


        /*
         * Remove from metabase all read/write/browse permission from certain subdirs 
         *
         */ 
        internal static void RestrictIISFolders(HttpContext context) { 
            int ret;
 
            HttpWorkerRequest wr = context.WorkerRequest;

            Debug.Assert(AppDomainAppIdInternal != null);
 
            // Don't do it if we are not running on IIS
            if (wr == null || !(wr is System.Web.Hosting.ISAPIWorkerRequest)) { 
                return; 
            }
 
            // Do it only for IIS 5
#if !FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
            if (!(wr is System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6))
#endif // !FEATURE_PAL 
 {
                byte[] bufin; 
                byte[] bufout = new byte[1];   // Just to keep EcbCallISAPI happy 

                bufin = BitConverter.GetBytes(UnsafeNativeMethods.RESTRICT_BIN); 
                ret = context.CallISAPI(UnsafeNativeMethods.CallISAPIFunc.RestrictIISFolders, bufin, bufout);
                if (ret != 1) {
                    // Cannot pass back any HR from inetinfo.exe because CSyncPipeManager::GetDataFromIIS
                    // does not support passing back any value when there is an error. 
                    Debug.Trace("RestrictIISFolders", "Cannot restrict folder access for '" + AppDomainAppIdInternal + "'.");
                } 
            } 
        }
 
        //
        // Helper to create instances (public vs. internal/private ctors, see 89781)
        //
 
        internal static Object CreateNonPublicInstance(Type type) {
            return CreateNonPublicInstance(type, null); 
        } 

        internal static Object CreateNonPublicInstance(Type type, Object[] args) { 
            return Activator.CreateInstance(
                type,
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance,
                null, 
                args,
                null); 
        } 

        internal static Object CreatePublicInstance(Type type) { 
            return Activator.CreateInstance(type);
        }

#if !DONTUSEFACTORYGENERATOR 
        // Cache instances of IWebObjectFactory for each Type, which allow us
        // to instantiate the objects very efficiently, compared to calling 
        // Activator.CreateInstance on every call. 
        private static FactoryGenerator s_factoryGenerator;
        private static Hashtable s_factoryCache; 
        private static bool s_initializedFactory;
        private static object s_factoryLock = new Object();

#endif // DONTUSEFACTORYGENERATOR 

        /* 
         * Faster implementation of CreatePublicInstance.  It generates bits of IL 
         * on the fly to achieve the improve performance.  this should only be used
         * in cases where the number of different types to be created is well bounded. 
         * Otherwise, we would create too much IL, which can bloat the process.
         */
        internal static Object FastCreatePublicInstance(Type type) {
 
#if DONTUSEFACTORYGENERATOR
            return CreatePublicInstance(type); 
#else 

            // Only use the factory logic if the assembly is in the GAC, to avoid getting 
            // assembly conflicts (VSWhidbey 405086)
            if (!type.Assembly.GlobalAssemblyCache) {
                return CreatePublicInstance(type);
            } 

            // Create the factory generator on demand 
            if (!s_initializedFactory) { 

                // Devdiv 90810 - Synchronize to avoid race condition 
                lock (s_factoryLock) {
                    if (!s_initializedFactory) {
                        s_factoryGenerator = new FactoryGenerator();
 
                        // Create the factory cache
                        s_factoryCache = Hashtable.Synchronized(new Hashtable()); 
 
                        s_initializedFactory = true;
                    } 
                }
            }

            // First, check if it's cached 
            IWebObjectFactory factory = (IWebObjectFactory)s_factoryCache[type];
 
            if (factory == null) { 

                Debug.Trace("FastCreatePublicInstance", "Creating generator for type " + type.FullName); 

                // Create the object factory
                factory = s_factoryGenerator.CreateFactory(type);
 
                // Cache the factory
                s_factoryCache[type] = factory; 
            } 

            return factory.CreateInstance(); 
#endif // DONTUSEFACTORYGENERATOR
        }

        internal static Object CreatePublicInstance(Type type, Object[] args) { 
            if (args == null)
                return Activator.CreateInstance(type); 
 
            return Activator.CreateInstance(type, args);
        } 

        static string GetCurrentUserName() {
            try {
                return WindowsIdentity.GetCurrent().Name; 
            }
            catch { 
                return null; 
            }
        } 

        void RaiseShutdownWebEventOnce() {
            if (!_shutdownWebEventRaised) {
                lock (this) { 
                    if (!_shutdownWebEventRaised) {
                        // Raise Web Event 
                        WebBaseEvent.RaiseSystemEvent(this, WebEventCodes.ApplicationShutdown, 
                                WebApplicationLifetimeEvent.DetailCodeFromShutdownReason(ShutdownReason));
 
                        _shutdownWebEventRaised = true;
                    }
                }
            } 
        }
    } 
 

    public enum ApplicationShutdownReason { 

        None = 0,

        HostingEnvironment = 1, 

        ChangeInGlobalAsax = 2, 
 
        ConfigurationChange = 3,
 
        UnloadAppDomainCalled = 4,

        ChangeInSecurityPolicyFile = 5,
 
        BinDirChangeOrDirectoryRename = 6,
 
        BrowsersDirChangeOrDirectoryRename = 7, 

        CodeDirChangeOrDirectoryRename = 8, 

        ResourcesDirChangeOrDirectoryRename = 9,

        IdleTimeout = 10, 

        PhysicalApplicationPathChanged = 11, 
 
        HttpRuntimeClose = 12,
 
        InitializationError = 13,

        MaxRecompilationsReached = 14,
 
        BuildManagerChange = 15,
    }; 
 

} 


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK