Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / Hosting / HostingEnvironment.cs / 1 / HostingEnvironment.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.Hosting {
using Microsoft.Win32;
using System;
using System.Configuration;
using System.Collections;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Compilation;
using System.Web.Configuration;
using System.Web.Util;
using System.Security;
using System.Security.Principal;
using System.Security.Permissions;
using System.Web.Management;
[Flags]
internal enum HostingEnvironmentFlags {
Default = 0,
HideFromAppManager = 1,
ThrowHostingInitErrors = 2,
DontCallAppInitialize = 4,
ClientBuildManager = 8,
}
[Serializable]
internal class HostingEnvironmentParameters {
private HostingEnvironmentFlags _hostingFlags;
private ClientBuildManagerParameter _clientBuildManagerParameter;
private string _precompTargetPhysicalDir;
public HostingEnvironmentFlags HostingFlags {
get { return _hostingFlags; }
set { _hostingFlags = value; }
}
// Directory where the precompiled site is placed
public string PrecompilationTargetPhysicalDirectory {
get { return _precompTargetPhysicalDir; }
set {
_precompTargetPhysicalDir = FileUtil.FixUpPhysicalDirectory(value);
}
}
// Determines the behavior of the precompilation
public ClientBuildManagerParameter ClientBuildManagerParameter {
get { return _clientBuildManagerParameter; }
set { _clientBuildManagerParameter = value; }
}
}
[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public sealed class HostingEnvironment : MarshalByRefObject {
private static HostingEnvironment _theHostingEnvironment;
private EventHandler _onAppDomainUnload;
private ApplicationManager _appManager;
private HostingEnvironmentParameters _hostingParameters;
private IApplicationHost _appHost;
private bool _externalAppHost;
private IConfigMapPath _configMapPath;
private IConfigMapPath2 _configMapPath2;
private IntPtr _configToken;
private IdentitySection _appIdentity;
private IntPtr _appIdentityToken;
private bool _appIdentityTokenSet;
private String _appId;
private VirtualPath _appVirtualPath;
private String _appPhysicalPath;
private String _siteName;
private String _siteID;
private String _appConfigPath;
private bool _isBusy;
private int _busyCount;
private bool _removedFromAppManager;
private bool _appDomainShutdownStarted;
private bool _shutdownInitated;
private bool _shutdownInProgress;
private String _shutDownStack;
// table of well know objects keyed by type
private Hashtable _wellKnownObjects = new Hashtable();
// list of registered IRegisteredObject instances
private Hashtable _registeredObjects = new Hashtable();
// callback to make InitiateShutdown non-blocking
private WaitCallback _initiateShutdownWorkItemCallback;
// inside app domain idle shutdown logic
private IdleTimeoutMonitor _idleTimeoutMonitor;
private static IProcessHostSupportFunctions _functions;
private static bool _hasBeenRemovedFromAppManangerTable;
public override Object InitializeLifetimeService() {
return null; // never expire lease
}
///
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public HostingEnvironment() {
if (_theHostingEnvironment != null)
throw new InvalidOperationException(SR.GetString(SR.Only_1_HostEnv));
// remember singleton HostingEnvironment in a static
_theHostingEnvironment = this;
// start watching for app domain unloading
_onAppDomainUnload = new EventHandler(OnAppDomainUnload);
Thread.GetDomain().DomainUnload += _onAppDomainUnload;
}
private void OnAppDomainUnload(Object unusedObject, EventArgs unusedEventArgs) {
Debug.Trace("PipelineRuntime", "HE.OnAppDomainUnload");
Thread.GetDomain().DomainUnload -= _onAppDomainUnload;
// check for unexpected shutdown
if (!_removedFromAppManager) {
RemoveThisAppDomainFromAppManagerTableOnce();
}
HttpRuntime.RecoverFromUnexceptedAppDomainUnload();
// call Stop on all registered objects with immediate = true
StopRegisteredObjects(true);
// notify app manager
if (_appManager != null) {
// disconnect the real app host and substitute it with a bogus one
// to avoid exceptions later when app host is called (it normally wouldn't)
IApplicationHost originalAppHost = null;
if (_externalAppHost) {
originalAppHost = _appHost;
_appHost = new SimpleApplicationHost(_appVirtualPath, _appPhysicalPath);
_externalAppHost = false;
}
_appManager.HostingEnvironmentShutdownComplete(_appId, originalAppHost);
}
// free the config access token
if (_configToken != IntPtr.Zero) {
UnsafeNativeMethods.CloseHandle(_configToken);
_configToken = IntPtr.Zero;
}
}
//
// Initialization
//
// called from app manager right after app domain (and hosting env) is created
internal void Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters) {
_hostingParameters = hostingParameters;
HostingEnvironmentFlags hostingFlags = HostingEnvironmentFlags.Default;
if (_hostingParameters != null)
hostingFlags = _hostingParameters.HostingFlags;
// Keep track of the app manager, unless HideFromAppManager flag was passed
if ((hostingFlags & HostingEnvironmentFlags.HideFromAppManager) == 0)
_appManager = appManager;
if ((hostingFlags & HostingEnvironmentFlags.ClientBuildManager) != 0) {
BuildManagerHost.InClientBuildManager = true;
}
//
// init config system using private config if applicable
//
if (appHost is ISAPIApplicationHost && !ServerConfig.UseMetabase) {
string rootWebConfigPath = ((ISAPIApplicationHost)appHost).ResolveRootWebConfigPath();
if (!String.IsNullOrEmpty(rootWebConfigPath)) {
Debug.Assert(File.Exists(rootWebConfigPath), "File.Exists(rootWebConfigPath)");
HttpConfigurationSystem.RootWebConfigurationFilePath = rootWebConfigPath;
}
// we need to explicit create a COM proxy in this app domain
// so we don't go back to the default domain or have lifetime issues
// remember support functions
IProcessHostSupportFunctions proxyFunctions = ((ISAPIApplicationHost)appHost).SupportFunctions;
if (null != proxyFunctions) {
_functions = Misc.CreateLocalSupportFunctions(proxyFunctions);
}
}
_appId = HttpRuntime.AppDomainAppIdInternal;
_appVirtualPath = HttpRuntime.AppDomainAppVirtualPathObject;
_appPhysicalPath = HttpRuntime.AppDomainAppPathInternal;
_appHost = appHost;
_configMapPath = configMapPathFactory.Create(_appVirtualPath.VirtualPathString, _appPhysicalPath);
HttpConfigurationSystem.EnsureInit(_configMapPath, true, false);
// attempt to cache and use IConfigMapPath2 provider
// which supports VirtualPath's to save on conversions
_configMapPath2 = _configMapPath as IConfigMapPath2;
_initiateShutdownWorkItemCallback = new WaitCallback(this.InitiateShutdownWorkItemCallback);
// notify app manager
if (_appManager != null) {
_appManager.HostingEnvironmentActivated(_appId);
}
// make sure there is always app host
if (_appHost == null) {
_appHost = new SimpleApplicationHost(_appVirtualPath, _appPhysicalPath);
}
else {
_externalAppHost = true;
}
// remember the token to access config
_configToken = _appHost.GetConfigToken();
// Start with a MapPath based virtual path provider
_mapPathBasedVirtualPathProvider = new MapPathBasedVirtualPathProvider();
_virtualPathProvider = _mapPathBasedVirtualPathProvider;
// initiaze HTTP-independent features
HttpRuntime.InitializeHostingFeatures(hostingFlags);
// VSWhidbey 393259. Do not monitor idle timeout for CBM since Venus
// will always restart a new appdomain if old one is shutdown.
if (!BuildManagerHost.InClientBuildManager) {
// start monitoring for idle inside app domain
StartMonitoringForIdleTimeout();
}
// notify app manager if the app domain limit is violated
EnforceAppDomainLimit();
// get application identity (for explicit impersonation mode)
GetApplicationIdentity();
// call AppInitialize, unless the flag says not to do it (e.g. CBM scenario).
// Also, don't call it if HostingInit failed (VSWhidbey 210495)
if ((hostingFlags & HostingEnvironmentFlags.DontCallAppInitialize) == 0 &&
!HttpRuntime.HostingInitFailed) {
try {
BuildManager.CallAppInitializeMethod();
}
catch (Exception e) {
// could throw compilation errors in 'code' - report them with first http request
HttpRuntime.InitializationException = e;
if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0) {
throw;
}
}
}
}
private void StartMonitoringForIdleTimeout() {
HostingEnvironmentSection hostEnvConfig = RuntimeConfig.GetAppLKGConfig().HostingEnvironment;
TimeSpan idleTimeout = (hostEnvConfig != null) ? hostEnvConfig.IdleTimeout : HostingEnvironmentSection.DefaultIdleTimeout;
// always create IdleTimeoutMonitor (even if config value is TimeSpan.MaxValue (infinite)
// IdleTimeoutMonitor is also needed to keep the last event for app domain set trimming
// and the timer is used to trim the application instances
_idleTimeoutMonitor = new IdleTimeoutMonitor(idleTimeout);
}
// enforce app domain limit
private void EnforceAppDomainLimit() {
if (_appManager == null) /// detached app domain
return;
int limit = 0;
try {
ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel;
limit = pmConfig.MaxAppDomains;
}
catch {
}
if (limit > 0 && _appManager.AppDomainsCount >= limit) {
// current app domain doesn't count yet (not in the table)
// that's why '>=' above
_appManager.ReduceAppDomainsCount(limit);
}
}
private void GetApplicationIdentity() {
// if the explicit impersonation is set, use it instead of UNC identity
try {
IdentitySection c = RuntimeConfig.GetAppConfig().Identity;
if (c.Impersonate && c.ImpersonateToken != IntPtr.Zero) {
_appIdentity = c;
_appIdentityToken = c.ImpersonateToken;
}
else {
_appIdentityToken = _configToken;
}
_appIdentityTokenSet = true;
}
catch {
}
}
// If an exception was thrown during initialization, return it.
public static Exception InitializationException {
get {
return HttpRuntime.InitializationException;
}
}
// called from app manager (from management APIs)
internal ApplicationInfo GetApplicationInfo() {
return new ApplicationInfo(_appId, _appVirtualPath, _appPhysicalPath);
}
//
// Shutdown logic
//
private void StopRegisteredObjects(bool immediate) {
if (_registeredObjects.Count > 0) {
ArrayList list = new ArrayList();
lock (this) {
foreach (DictionaryEntry e in _registeredObjects) {
Object x = e.Key;
// well-known objects first
if (IsWellKnownObject(x)) {
list.Insert(0, x);
}
else {
list.Add(x);
}
}
}
foreach (IRegisteredObject obj in list) {
try {
obj.Stop(immediate);
}
catch {
}
}
}
}
private void InitiateShutdownWorkItemCallback(Object state /*not used*/) {
Debug.Trace("HostingEnvironmentShutdown", "Shutting down: appId=" + _appId);
// no registered objects -- shutdown
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "No registered objects");
ShutdownThisAppDomainOnce();
return;
}
// call Stop on all registered objects with immediate = false
StopRegisteredObjects(false);
// no registered objects -- shutdown now
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "All registered objects gone after Stop(false)");
ShutdownThisAppDomainOnce();
return;
}
// if not everything shutdown synchronously give it some time.
int shutdownTimeoutSeconds = HostingEnvironmentSection.DefaultShutdownTimeout;
HostingEnvironmentSection hostEnvConfig = RuntimeConfig.GetAppLKGConfig().HostingEnvironment;
if (hostEnvConfig != null) {
shutdownTimeoutSeconds = (int) hostEnvConfig.ShutdownTimeout.TotalSeconds;
}
Debug.Trace("HostingEnvironmentShutdown", "Waiting for " + shutdownTimeoutSeconds + " sec...");
DateTime waitUntil = DateTime.UtcNow.AddSeconds(shutdownTimeoutSeconds);
while (_registeredObjects.Count > 0 && DateTime.UtcNow < waitUntil) {
Thread.Sleep(100);
}
Debug.Trace("HostingEnvironmentShutdown", "Shutdown timeout (" + shutdownTimeoutSeconds + " sec) expired");
// call Stop on all registered objects with immediate = true
StopRegisteredObjects(true);
// no registered objects -- shutdown now
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "All registered objects gone after Stop(true)");
ShutdownThisAppDomainOnce();
return;
}
// shutdown regardless
Debug.Trace("HostingEnvironmentShutdown", "Forced shutdown: " + _registeredObjects.Count + " registered objects left");
_registeredObjects = new Hashtable();
ShutdownThisAppDomainOnce();
}
// app domain shutdown logic
internal void InitiateShutdownInternal() {
Debug.Trace("AppManager", "HostingEnvironment.InitiateShutdownInternal appId=" + _appId);
bool proceed = false;
if (!_shutdownInitated) {
lock (this) {
if (!_shutdownInitated) {
_shutdownInProgress = true;
proceed = true;
_shutdownInitated = true;
}
}
}
if (!proceed) {
return;
}
HttpRuntime.SetShutdownReason(ApplicationShutdownReason.HostingEnvironment, "HostingEnvironment initiated shutdown");
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
try {
_shutDownStack = Environment.StackTrace;
}
finally {
CodeAccessPermission.RevertAssert();
}
RemoveThisAppDomainFromAppManagerTableOnce();
// stop all registered objects without blocking
ThreadPool.QueueUserWorkItem(this._initiateShutdownWorkItemCallback);
}
internal bool HasBeenRemovedFromAppManagerTable {
get {
return _hasBeenRemovedFromAppManangerTable;
}
set {
_hasBeenRemovedFromAppManangerTable = value;
}
}
private void RemoveThisAppDomainFromAppManagerTableOnce() {
bool proceed = false;
if (!_removedFromAppManager) {
lock (this) {
if (!_removedFromAppManager) {
proceed = true;
_removedFromAppManager = true;
}
}
}
if (!proceed)
return;
if (_appManager != null) {
Debug.Trace("AppManager", "Removing HostingEnvironment from AppManager table, appId=" + _appId);
_appManager.HostingEnvironmentShutdownInitiated(_appId, this);
}
}
private void ShutdownThisAppDomainOnce() {
bool proceed = false;
if (!_appDomainShutdownStarted) {
lock (this) {
if (!_appDomainShutdownStarted) {
proceed = true;
_appDomainShutdownStarted = true;
}
}
}
if (!proceed)
return;
Debug.Trace("AppManager", "HostingEnvironment - shutting down AppDomain, appId=" + _appId);
// stop the timer used for idle timeout
if (_idleTimeoutMonitor != null) {
_idleTimeoutMonitor.Stop();
_idleTimeoutMonitor = null;
}
//
HttpRuntime.SetUserForcedShutdown();
//WOS 1400290: CantUnloadAppDomainException in ISAPI mode, wait until HostingEnvironment.ShutdownThisAppDomainOnce completes
_shutdownInProgress = false;
HttpRuntime.ShutdownAppDomainWithStackTrace(ApplicationShutdownReason.HostingEnvironment,
SR.GetString(SR.Hosting_Env_Restart),
_shutDownStack);
}
//
// internal methods called by app manager
//
// helper for app manager to implement AppHost.CreateAppHost
internal ObjectHandle CreateInstance(Type type) {
return new ObjectHandle(Activator.CreateInstance(type));
}
// start well known object
internal ObjectHandle CreateWellKnownObjectInstance(Type type, bool failIfExists) {
IRegisteredObject obj = null;
String key = type.FullName;
bool exists = false;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
if (obj == null) {
obj = (IRegisteredObject)Activator.CreateInstance(type);
_wellKnownObjects[key] = obj;
}
else {
exists = true;
}
}
if (exists && failIfExists) {
throw new InvalidOperationException(SR.GetString(SR.Wellknown_object_already_exists, key));
}
return new ObjectHandle(obj);
}
// check if well known object
private bool IsWellKnownObject(Object obj) {
bool found = false;
String key = obj.GetType().FullName;
lock (this) {
if (_wellKnownObjects[key] == obj) {
found = true;
}
}
return found;
}
// find well known object by type
internal ObjectHandle FindWellKnownObject(Type type) {
IRegisteredObject obj = null;
String key = type.FullName;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
}
return (obj != null) ? new ObjectHandle(obj) : null;
}
// stop well known object by type
internal void StopWellKnownObject(Type type) {
IRegisteredObject obj = null;
String key = type.FullName;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
if (obj != null) {
_wellKnownObjects.Remove(key);
obj.Stop(false);
}
}
}
internal bool IsIdle() {
bool isBusy = _isBusy;
_isBusy = false;
return (!isBusy && _busyCount == 0);
}
internal bool GetIdleValue() {
return (!_isBusy && _busyCount == 0);
}
internal void IncrementBusyCountInternal() {
_isBusy = true;
Interlocked.Increment(ref _busyCount);
}
internal void DecrementBusyCountInternal() {
_isBusy = true;
Interlocked.Decrement(ref _busyCount);
// Notify idle timeout monitor
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm != null) {
itm.LastEvent = DateTime.UtcNow;
}
}
internal void IsUnloaded()
{
return;
}
private void MessageReceivedInternal() {
_isBusy = true;
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm != null) {
itm.LastEvent = DateTime.UtcNow;
}
}
// the busier the app domain the higher the score
internal int LruScore {
get {
if (_busyCount > 0)
return _busyCount;
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm == null)
return 0;
// return negative number of seconds since last activity
return -(int)(DateTime.UtcNow - itm.LastEvent).TotalSeconds;
}
}
internal static ApplicationManager GetApplicationManager() {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appManager;
}
//
// private helpers
//
// register protocol handler with hosting environment
private void RegisterRunningObjectInternal(IRegisteredObject obj) {
lock (this) {
_registeredObjects[obj] = obj;
}
}
// unregister protocol handler from hosting environment
private void UnregisterRunningObjectInternal(IRegisteredObject obj) {
bool lastOne = false;
lock (this) {
// if it is a well known object, remove it from that table as well
String key = obj.GetType().FullName;
if (_wellKnownObjects[key] == obj) {
_wellKnownObjects.Remove(key);
}
// remove from running objects list
_registeredObjects.Remove(obj);
if (_registeredObjects.Count == 0)
lastOne = true;
}
if (!lastOne)
return;
// shutdown app domain after last protocol handler is gone
InitiateShutdownInternal();
}
// site name
private String GetSiteName() {
if (_siteName == null) {
lock (this) {
if (_siteName == null) {
String s = null;
if (_appHost != null) {
//
InternalSecurityPermissions.Unrestricted.Assert();
try {
s = _appHost.GetSiteName();
}
finally {
CodeAccessPermission.RevertAssert();
}
}
if (s == null)
s = WebConfigurationHost.DefaultSiteName;
_siteName = s;
}
}
}
return _siteName;
}
// site ID
private String GetSiteID() {
if (_siteID == null) {
lock (this) {
if (_siteID == null) {
String s = null;
if (_appHost != null) {
//
InternalSecurityPermissions.Unrestricted.Assert();
try {
s = _appHost.GetSiteID();
}
finally {
CodeAccessPermission.RevertAssert();
}
}
if (s == null)
s = WebConfigurationHost.DefaultSiteID;
_siteID = s.ToLower(CultureInfo.InvariantCulture);
}
}
}
return _siteID;
}
// Return the configPath for the app, e.g. "machine/webroot/1/myapp"
private String GetAppConfigPath() {
if (_appConfigPath == null) {
_appConfigPath = WebConfigurationHost.GetConfigPathFromSiteIDAndVPath(SiteID, ApplicationVirtualPathObject);
}
return _appConfigPath;
}
// Return the call context slot name to use for a virtual path
private static string GetFixedMappingSlotName(VirtualPath virtualPath) {
return "MapPath_" + virtualPath.VirtualPathString.ToLowerInvariant().GetHashCode().ToString(CultureInfo.InvariantCulture);
}
/*
* Map a virtual path to a physical path. i.e. the physicalPath will be returned
* when MapPath is called on the virtual path, bypassing the IApplicationHost
*/
private static string GetVirtualPathToFileMapping(VirtualPath virtualPath) {
return CallContext.GetData(GetFixedMappingSlotName(virtualPath)) as string;
}
/*
* Map a virtual path to a physical path. i.e. the physicalPath will be returned
* when MapPath is called on the virtual path, bypassing the IApplicationHost
*/
internal static object AddVirtualPathToFileMapping(
VirtualPath virtualPath, string physicalPath) {
// Save the mapping in the call context, using a key derived from the
// virtual path. The mapping is only valid for the duration of the request.
CallContext.SetData(GetFixedMappingSlotName(virtualPath), physicalPath);
// Return a mapping object to keep track of the virtual path, and of the current
// virtualPathProvider.
VirtualPathToFileMappingState state = new VirtualPathToFileMappingState();
state.VirtualPath = virtualPath;
state.VirtualPathProvider = _theHostingEnvironment._virtualPathProvider;
// Always use the MapPathBasedVirtualPathProvider, otherwise the mapping mechanism
// doesn't work (VSWhidbey 420702)
_theHostingEnvironment._virtualPathProvider = _theHostingEnvironment._mapPathBasedVirtualPathProvider;
return state;
}
internal static void ClearVirtualPathToFileMapping(object state) {
VirtualPathToFileMappingState mapping = (VirtualPathToFileMappingState)state;
// Clear the mapping from the call context
CallContext.SetData(GetFixedMappingSlotName(mapping.VirtualPath), null);
// Restore the previous VirtualPathProvider
_theHostingEnvironment._virtualPathProvider = mapping.VirtualPathProvider;
}
private string MapPathActual(VirtualPath virtualPath, bool permitNull)
{
string result = null;
Debug.Assert(virtualPath != null);
virtualPath.FailIfRelativePath();
VirtualPath reqpath = virtualPath;
if (String.CompareOrdinal(reqpath.VirtualPathString, _appVirtualPath.VirtualPathString) == 0) {
// for application path don't need to call app host
Debug.Trace("MapPath", reqpath +" is the app path");
result = _appPhysicalPath;
}
else {
using (new ProcessImpersonationContext()) {
// If there is a mapping for this virtual path in the call context, use it
result = GetVirtualPathToFileMapping(reqpath);
if (result == null) {
// call host's mappath
if (_configMapPath == null) {
Debug.Trace("MapPath", "Missing _configMapPath");
throw new InvalidOperationException(SR.GetString(SR.Cannot_map_path, reqpath));
}
Debug.Trace("MapPath", "call ConfigMapPath (" + reqpath + ")");
// see if the IConfigMapPath provider implements the interface
// with VirtualPath
if (null != _configMapPath2) {
result = _configMapPath2.MapPath(GetSiteID(), reqpath);
}
else {
result = _configMapPath.MapPath(GetSiteID(), reqpath.VirtualPathString);
}
}
}
}
if (String.IsNullOrEmpty(result)) {
Debug.Trace("MapPath", "null Result");
if (!permitNull) {
throw new InvalidOperationException(SR.GetString(SR.Cannot_map_path, reqpath));
}
}
else {
// ensure extra '\\' in the physical path if the virtual path had extra '/'
// and the other way -- no extra '\\' in physical if virtual didn't have it.
if (virtualPath.HasTrailingSlash) {
if (!UrlPath.PathEndsWithExtraSlash(result) && !UrlPath.PathIsDriveRoot(result))
result = result + "\\";
}
else {
if (UrlPath.PathEndsWithExtraSlash(result) && !UrlPath.PathIsDriveRoot(result))
result = result.Substring(0, result.Length - 1);
}
Debug.Trace("MapPath", " result=" + result);
}
return result;
}
//
// public static methods
//
// register protocol handler with hosting environment
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void RegisterObject(IRegisteredObject obj) {
if (_theHostingEnvironment != null)
_theHostingEnvironment.RegisterRunningObjectInternal(obj);
}
// unregister protocol handler from hosting environment
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void UnregisterObject(IRegisteredObject obj) {
if (_theHostingEnvironment != null)
_theHostingEnvironment.UnregisterRunningObjectInternal(obj);
}
//
// public static methods for the user code to call
//
public static void IncrementBusyCount() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.IncrementBusyCountInternal();
}
public static void DecrementBusyCount() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.DecrementBusyCountInternal();
}
public static void MessageReceived() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.MessageReceivedInternal();
}
public static bool IsHosted {
get {
return (_theHostingEnvironment != null);
}
}
internal static bool IsUnderIISProcess {
get {
String process = VersionInfo.ExeName;
return process == "aspnet_wp" ||
process == "w3wp" ||
process == "inetinfo";
}
}
internal static bool IsUnderIIS6Process {
get {
return VersionInfo.ExeName == "w3wp";
}
}
public static IApplicationHost ApplicationHost {
//DevDivBugs 109864: ASP.NET: path discovery issue - In low trust, it is possible to get the physical path of any virtual path on the machine
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appHost;
}
}
internal IApplicationHost InternalApplicationHost {
get {
return _appHost;
}
}
internal static int BusyCount {
get {
if (_theHostingEnvironment == null)
return 0;
return _theHostingEnvironment._busyCount;
}
}
internal static bool ShutdownInitiated {
get {
if (_theHostingEnvironment == null)
return false;
return _theHostingEnvironment._shutdownInitated;
}
}
internal static bool ShutdownInProgress {
get {
if (_theHostingEnvironment == null)
return false;
return _theHostingEnvironment._shutdownInProgress;
}
}
///
/// The application ID (metabase path in IIS hosting).
///
public static String ApplicationID {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AspNetHostingPermissionLevelHigh.Demand();
return _theHostingEnvironment._appId;
}
}
internal static String ApplicationIDNoDemand {
get {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment._appId;
}
}
///
/// Physical path to the application root.
///
public static String ApplicationPhysicalPath {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AppPathDiscovery.Demand();
return _theHostingEnvironment._appPhysicalPath;
}
}
///
/// Virtual path to the application root.
///
public static String ApplicationVirtualPath {
get {
return VirtualPath.GetVirtualPathStringNoTrailingSlash(ApplicationVirtualPathObject);
}
}
internal static VirtualPath ApplicationVirtualPathObject {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appVirtualPath;
}
}
///
/// Site name.
///
public static String SiteName {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AspNetHostingPermissionLevelMedium.Demand();
return _theHostingEnvironment.GetSiteName();
}
}
internal static String SiteNameNoDemand {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment.GetSiteName();
}
}
internal static String SiteID {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment.GetSiteID();
}
}
internal static IConfigMapPath ConfigMapPath {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._configMapPath;
}
}
internal static String AppConfigPath {
get {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.GetAppConfigPath();
}
}
///
///
/// Gets a reference to the System.Web.Cache.Cache object for the current request.
///
///
public static Cache Cache {
get { return HttpRuntime.Cache; }
}
// count of all app domain from app manager
internal static int AppDomainsCount {
get {
ApplicationManager appManager = GetApplicationManager();
return (appManager != null) ? appManager.AppDomainsCount : 0;
}
}
internal static HostingEnvironmentParameters HostingParameters {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._hostingParameters;
}
}
// Return an integer that is unique for each appdomain. This can be used
// to create things like once-per-appdomain temp files without having different
// processes/appdomains step on each other
private static int s_appDomainUniqueInteger;
internal static int AppDomainUniqueInteger {
get {
if (s_appDomainUniqueInteger == 0) {
s_appDomainUniqueInteger = Guid.NewGuid().GetHashCode();
}
return s_appDomainUniqueInteger;
}
}
public static ApplicationShutdownReason ShutdownReason {
get { return HttpRuntime.ShutdownReason; }
}
///
/// Initiate app domain unloading for the current app.
///
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void InitiateShutdown() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.InitiateShutdownInternal();
}
///
/// Maps a virtual path to a physical path.
///
public static string MapPath(string virtualPath) {
return MapPath(VirtualPath.Create(virtualPath));
}
internal static string MapPath(VirtualPath virtualPath) {
if (_theHostingEnvironment == null)
return null;
String path = MapPathInternal(virtualPath);
if (path != null)
InternalSecurityPermissions.PathDiscovery(path).Demand();
return path;
}
internal static String MapPathInternal(string virtualPath) {
return MapPathInternal(VirtualPath.Create(virtualPath));
}
internal static String MapPathInternal(VirtualPath virtualPath) {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.MapPathActual(virtualPath, false);
}
internal static String MapPathInternal(string virtualPath, bool permitNull) {
return MapPathInternal(VirtualPath.Create(virtualPath), permitNull);
}
internal static String MapPathInternal(VirtualPath virtualPath, bool permitNull) {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.MapPathActual(virtualPath, permitNull);
}
internal static string MapPathInternal(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping) {
return MapPathInternal(VirtualPath.Create(virtualPath),
VirtualPath.CreateNonRelative(baseVirtualDir), allowCrossAppMapping);
}
internal static string MapPathInternal(VirtualPath virtualPath, VirtualPath baseVirtualDir, bool allowCrossAppMapping) {
Debug.Assert(baseVirtualDir != null, "baseVirtualDir != null");
// Combine it with the base and reduce
virtualPath = baseVirtualDir.Combine(virtualPath);
if (!allowCrossAppMapping && !virtualPath.IsWithinAppRoot)
throw new ArgumentException(SR.GetString(SR.Cross_app_not_allowed, virtualPath));
return MapPathInternal(virtualPath);
}
internal static WebApplicationLevel GetPathLevel(String path) {
WebApplicationLevel pathLevel = WebApplicationLevel.AboveApplication;
if (_theHostingEnvironment != null && !String.IsNullOrEmpty(path)) {
String appPath = ApplicationVirtualPath;
if (appPath == "/") {
if (path == "/") {
pathLevel = WebApplicationLevel.AtApplication;
}
else if (path[0] == '/') {
pathLevel = WebApplicationLevel.BelowApplication;
}
}
else {
if (StringUtil.EqualsIgnoreCase(appPath, path)) {
pathLevel = WebApplicationLevel.AtApplication;
}
else if (path.Length > appPath.Length && path[appPath.Length] == '/' &&
StringUtil.StringStartsWithIgnoreCase(path, appPath)) {
pathLevel = WebApplicationLevel.BelowApplication;
}
}
}
return pathLevel;
}
//
// Impersonation helpers
//
// user token for the app (hosting / unc)
internal static IntPtr ApplicationIdentityToken {
get {
if (_theHostingEnvironment == null) {
return IntPtr.Zero;
}
else {
if (_theHostingEnvironment._appIdentityTokenSet)
return _theHostingEnvironment._appIdentityToken;
else
return _theHostingEnvironment._configToken;
}
}
}
// check if application impersonation != process impersonation
internal static bool HasHostingIdentity {
get {
return (ApplicationIdentityToken != IntPtr.Zero);
}
}
// impersonate application identity
[SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)]
public static IDisposable Impersonate() {
return new ApplicationImpersonationContext();
}
// impersonate the given user identity
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static IDisposable Impersonate(IntPtr token) {
if (token == IntPtr.Zero) {
return new ProcessImpersonationContext();
}
else {
return new ImpersonationContext(token);
}
}
// impersonate as configured for a given path
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static IDisposable Impersonate(IntPtr userToken, String virtualPath) {
virtualPath = UrlPath.MakeVirtualPathAppAbsoluteReduceAndCheck(virtualPath);
if (_theHostingEnvironment == null) {
return Impersonate(userToken);
}
IdentitySection c = RuntimeConfig.GetConfig(virtualPath).Identity;
if (c.Impersonate) {
if (c.ImpersonateToken != IntPtr.Zero) {
return new ImpersonationContext(c.ImpersonateToken);
}
else {
return new ImpersonationContext(userToken);
}
}
else {
return new ApplicationImpersonationContext();
}
}
//
// Culture helpers
//
public static IDisposable SetCultures() {
return SetCultures(RuntimeConfig.GetAppLKGConfig().Globalization);
}
public static IDisposable SetCultures(string virtualPath) {
virtualPath = UrlPath.MakeVirtualPathAppAbsoluteReduceAndCheck(virtualPath);
return SetCultures(RuntimeConfig.GetConfig(virtualPath).Globalization);
}
private static IDisposable SetCultures(GlobalizationSection gs) {
CultureContext c = new CultureContext();
if (gs != null) {
CultureInfo culture = null;
CultureInfo uiCulture = null;
if (gs.Culture != null && gs.Culture.Length > 0) {
try {
culture = HttpServerUtility.CreateReadOnlyCultureInfo(gs.Culture);
}
catch {
}
}
if (gs.UICulture != null && gs.UICulture.Length > 0) {
try {
uiCulture = HttpServerUtility.CreateReadOnlyCultureInfo(gs.UICulture);
}
catch {
}
}
c.SetCultures(culture, uiCulture);
}
return c;
}
class CultureContext : IDisposable {
CultureInfo _savedCulture;
CultureInfo _savedUICulture;
internal CultureContext() {
}
void IDisposable.Dispose() {
RestoreCultures();
}
internal void SetCultures(CultureInfo culture, CultureInfo uiCulture) {
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
if (culture != null && culture != currentCulture) {
Thread.CurrentThread.CurrentCulture = culture;
_savedCulture = currentCulture;
}
if (uiCulture != null && uiCulture != currentCulture) {
Thread.CurrentThread.CurrentUICulture = uiCulture;
_savedUICulture = currentUICulture;
}
}
internal void RestoreCultures() {
if (_savedCulture != null && _savedCulture != Thread.CurrentThread.CurrentCulture) {
Thread.CurrentThread.CurrentCulture = _savedCulture;
_savedCulture = null;
}
if (_savedUICulture != null && _savedUICulture != Thread.CurrentThread.CurrentUICulture) {
Thread.CurrentThread.CurrentUICulture = _savedUICulture;
_savedUICulture = null;
}
}
}
//
// VirtualPathProvider related code
//
private VirtualPathProvider _virtualPathProvider;
private VirtualPathProvider _mapPathBasedVirtualPathProvider;
public static VirtualPathProvider VirtualPathProvider {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._virtualPathProvider;
}
}
internal static bool UsingMapPathBasedVirtualPathProvider {
get {
if (_theHostingEnvironment == null)
return true;
return (_theHostingEnvironment._virtualPathProvider ==
_theHostingEnvironment._mapPathBasedVirtualPathProvider);
}
}
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
public static void RegisterVirtualPathProvider(VirtualPathProvider virtualPathProvider) {
if (_theHostingEnvironment == null)
throw new InvalidOperationException();
// Ignore the VirtualPathProvider on precompiled sites (VSWhidbey 368169,404844)
if (BuildManager.IsPrecompiledApp)
return;
RegisterVirtualPathProviderInternal(virtualPathProvider);
}
internal static void RegisterVirtualPathProviderInternal(VirtualPathProvider virtualPathProvider) {
VirtualPathProvider previous = _theHostingEnvironment._virtualPathProvider;
_theHostingEnvironment._virtualPathProvider = virtualPathProvider;
// Give it the previous provider so it can delegate if needed
virtualPathProvider.Initialize(previous);
}
// Helper class used to keep track of state when using
// AddVirtualPathToFileMapping & ClearVirtualPathToFileMapping
internal class VirtualPathToFileMappingState {
internal VirtualPath VirtualPath;
internal VirtualPathProvider VirtualPathProvider;
}
internal static IProcessHostSupportFunctions SupportFunctions {
get {
return _functions;
}
set {
_functions = value;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.Hosting {
using Microsoft.Win32;
using System;
using System.Configuration;
using System.Collections;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Compilation;
using System.Web.Configuration;
using System.Web.Util;
using System.Security;
using System.Security.Principal;
using System.Security.Permissions;
using System.Web.Management;
[Flags]
internal enum HostingEnvironmentFlags {
Default = 0,
HideFromAppManager = 1,
ThrowHostingInitErrors = 2,
DontCallAppInitialize = 4,
ClientBuildManager = 8,
}
[Serializable]
internal class HostingEnvironmentParameters {
private HostingEnvironmentFlags _hostingFlags;
private ClientBuildManagerParameter _clientBuildManagerParameter;
private string _precompTargetPhysicalDir;
public HostingEnvironmentFlags HostingFlags {
get { return _hostingFlags; }
set { _hostingFlags = value; }
}
// Directory where the precompiled site is placed
public string PrecompilationTargetPhysicalDirectory {
get { return _precompTargetPhysicalDir; }
set {
_precompTargetPhysicalDir = FileUtil.FixUpPhysicalDirectory(value);
}
}
// Determines the behavior of the precompilation
public ClientBuildManagerParameter ClientBuildManagerParameter {
get { return _clientBuildManagerParameter; }
set { _clientBuildManagerParameter = value; }
}
}
[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public sealed class HostingEnvironment : MarshalByRefObject {
private static HostingEnvironment _theHostingEnvironment;
private EventHandler _onAppDomainUnload;
private ApplicationManager _appManager;
private HostingEnvironmentParameters _hostingParameters;
private IApplicationHost _appHost;
private bool _externalAppHost;
private IConfigMapPath _configMapPath;
private IConfigMapPath2 _configMapPath2;
private IntPtr _configToken;
private IdentitySection _appIdentity;
private IntPtr _appIdentityToken;
private bool _appIdentityTokenSet;
private String _appId;
private VirtualPath _appVirtualPath;
private String _appPhysicalPath;
private String _siteName;
private String _siteID;
private String _appConfigPath;
private bool _isBusy;
private int _busyCount;
private bool _removedFromAppManager;
private bool _appDomainShutdownStarted;
private bool _shutdownInitated;
private bool _shutdownInProgress;
private String _shutDownStack;
// table of well know objects keyed by type
private Hashtable _wellKnownObjects = new Hashtable();
// list of registered IRegisteredObject instances
private Hashtable _registeredObjects = new Hashtable();
// callback to make InitiateShutdown non-blocking
private WaitCallback _initiateShutdownWorkItemCallback;
// inside app domain idle shutdown logic
private IdleTimeoutMonitor _idleTimeoutMonitor;
private static IProcessHostSupportFunctions _functions;
private static bool _hasBeenRemovedFromAppManangerTable;
public override Object InitializeLifetimeService() {
return null; // never expire lease
}
///
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public HostingEnvironment() {
if (_theHostingEnvironment != null)
throw new InvalidOperationException(SR.GetString(SR.Only_1_HostEnv));
// remember singleton HostingEnvironment in a static
_theHostingEnvironment = this;
// start watching for app domain unloading
_onAppDomainUnload = new EventHandler(OnAppDomainUnload);
Thread.GetDomain().DomainUnload += _onAppDomainUnload;
}
private void OnAppDomainUnload(Object unusedObject, EventArgs unusedEventArgs) {
Debug.Trace("PipelineRuntime", "HE.OnAppDomainUnload");
Thread.GetDomain().DomainUnload -= _onAppDomainUnload;
// check for unexpected shutdown
if (!_removedFromAppManager) {
RemoveThisAppDomainFromAppManagerTableOnce();
}
HttpRuntime.RecoverFromUnexceptedAppDomainUnload();
// call Stop on all registered objects with immediate = true
StopRegisteredObjects(true);
// notify app manager
if (_appManager != null) {
// disconnect the real app host and substitute it with a bogus one
// to avoid exceptions later when app host is called (it normally wouldn't)
IApplicationHost originalAppHost = null;
if (_externalAppHost) {
originalAppHost = _appHost;
_appHost = new SimpleApplicationHost(_appVirtualPath, _appPhysicalPath);
_externalAppHost = false;
}
_appManager.HostingEnvironmentShutdownComplete(_appId, originalAppHost);
}
// free the config access token
if (_configToken != IntPtr.Zero) {
UnsafeNativeMethods.CloseHandle(_configToken);
_configToken = IntPtr.Zero;
}
}
//
// Initialization
//
// called from app manager right after app domain (and hosting env) is created
internal void Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters) {
_hostingParameters = hostingParameters;
HostingEnvironmentFlags hostingFlags = HostingEnvironmentFlags.Default;
if (_hostingParameters != null)
hostingFlags = _hostingParameters.HostingFlags;
// Keep track of the app manager, unless HideFromAppManager flag was passed
if ((hostingFlags & HostingEnvironmentFlags.HideFromAppManager) == 0)
_appManager = appManager;
if ((hostingFlags & HostingEnvironmentFlags.ClientBuildManager) != 0) {
BuildManagerHost.InClientBuildManager = true;
}
//
// init config system using private config if applicable
//
if (appHost is ISAPIApplicationHost && !ServerConfig.UseMetabase) {
string rootWebConfigPath = ((ISAPIApplicationHost)appHost).ResolveRootWebConfigPath();
if (!String.IsNullOrEmpty(rootWebConfigPath)) {
Debug.Assert(File.Exists(rootWebConfigPath), "File.Exists(rootWebConfigPath)");
HttpConfigurationSystem.RootWebConfigurationFilePath = rootWebConfigPath;
}
// we need to explicit create a COM proxy in this app domain
// so we don't go back to the default domain or have lifetime issues
// remember support functions
IProcessHostSupportFunctions proxyFunctions = ((ISAPIApplicationHost)appHost).SupportFunctions;
if (null != proxyFunctions) {
_functions = Misc.CreateLocalSupportFunctions(proxyFunctions);
}
}
_appId = HttpRuntime.AppDomainAppIdInternal;
_appVirtualPath = HttpRuntime.AppDomainAppVirtualPathObject;
_appPhysicalPath = HttpRuntime.AppDomainAppPathInternal;
_appHost = appHost;
_configMapPath = configMapPathFactory.Create(_appVirtualPath.VirtualPathString, _appPhysicalPath);
HttpConfigurationSystem.EnsureInit(_configMapPath, true, false);
// attempt to cache and use IConfigMapPath2 provider
// which supports VirtualPath's to save on conversions
_configMapPath2 = _configMapPath as IConfigMapPath2;
_initiateShutdownWorkItemCallback = new WaitCallback(this.InitiateShutdownWorkItemCallback);
// notify app manager
if (_appManager != null) {
_appManager.HostingEnvironmentActivated(_appId);
}
// make sure there is always app host
if (_appHost == null) {
_appHost = new SimpleApplicationHost(_appVirtualPath, _appPhysicalPath);
}
else {
_externalAppHost = true;
}
// remember the token to access config
_configToken = _appHost.GetConfigToken();
// Start with a MapPath based virtual path provider
_mapPathBasedVirtualPathProvider = new MapPathBasedVirtualPathProvider();
_virtualPathProvider = _mapPathBasedVirtualPathProvider;
// initiaze HTTP-independent features
HttpRuntime.InitializeHostingFeatures(hostingFlags);
// VSWhidbey 393259. Do not monitor idle timeout for CBM since Venus
// will always restart a new appdomain if old one is shutdown.
if (!BuildManagerHost.InClientBuildManager) {
// start monitoring for idle inside app domain
StartMonitoringForIdleTimeout();
}
// notify app manager if the app domain limit is violated
EnforceAppDomainLimit();
// get application identity (for explicit impersonation mode)
GetApplicationIdentity();
// call AppInitialize, unless the flag says not to do it (e.g. CBM scenario).
// Also, don't call it if HostingInit failed (VSWhidbey 210495)
if ((hostingFlags & HostingEnvironmentFlags.DontCallAppInitialize) == 0 &&
!HttpRuntime.HostingInitFailed) {
try {
BuildManager.CallAppInitializeMethod();
}
catch (Exception e) {
// could throw compilation errors in 'code' - report them with first http request
HttpRuntime.InitializationException = e;
if ((hostingFlags & HostingEnvironmentFlags.ThrowHostingInitErrors) != 0) {
throw;
}
}
}
}
private void StartMonitoringForIdleTimeout() {
HostingEnvironmentSection hostEnvConfig = RuntimeConfig.GetAppLKGConfig().HostingEnvironment;
TimeSpan idleTimeout = (hostEnvConfig != null) ? hostEnvConfig.IdleTimeout : HostingEnvironmentSection.DefaultIdleTimeout;
// always create IdleTimeoutMonitor (even if config value is TimeSpan.MaxValue (infinite)
// IdleTimeoutMonitor is also needed to keep the last event for app domain set trimming
// and the timer is used to trim the application instances
_idleTimeoutMonitor = new IdleTimeoutMonitor(idleTimeout);
}
// enforce app domain limit
private void EnforceAppDomainLimit() {
if (_appManager == null) /// detached app domain
return;
int limit = 0;
try {
ProcessModelSection pmConfig = RuntimeConfig.GetMachineConfig().ProcessModel;
limit = pmConfig.MaxAppDomains;
}
catch {
}
if (limit > 0 && _appManager.AppDomainsCount >= limit) {
// current app domain doesn't count yet (not in the table)
// that's why '>=' above
_appManager.ReduceAppDomainsCount(limit);
}
}
private void GetApplicationIdentity() {
// if the explicit impersonation is set, use it instead of UNC identity
try {
IdentitySection c = RuntimeConfig.GetAppConfig().Identity;
if (c.Impersonate && c.ImpersonateToken != IntPtr.Zero) {
_appIdentity = c;
_appIdentityToken = c.ImpersonateToken;
}
else {
_appIdentityToken = _configToken;
}
_appIdentityTokenSet = true;
}
catch {
}
}
// If an exception was thrown during initialization, return it.
public static Exception InitializationException {
get {
return HttpRuntime.InitializationException;
}
}
// called from app manager (from management APIs)
internal ApplicationInfo GetApplicationInfo() {
return new ApplicationInfo(_appId, _appVirtualPath, _appPhysicalPath);
}
//
// Shutdown logic
//
private void StopRegisteredObjects(bool immediate) {
if (_registeredObjects.Count > 0) {
ArrayList list = new ArrayList();
lock (this) {
foreach (DictionaryEntry e in _registeredObjects) {
Object x = e.Key;
// well-known objects first
if (IsWellKnownObject(x)) {
list.Insert(0, x);
}
else {
list.Add(x);
}
}
}
foreach (IRegisteredObject obj in list) {
try {
obj.Stop(immediate);
}
catch {
}
}
}
}
private void InitiateShutdownWorkItemCallback(Object state /*not used*/) {
Debug.Trace("HostingEnvironmentShutdown", "Shutting down: appId=" + _appId);
// no registered objects -- shutdown
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "No registered objects");
ShutdownThisAppDomainOnce();
return;
}
// call Stop on all registered objects with immediate = false
StopRegisteredObjects(false);
// no registered objects -- shutdown now
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "All registered objects gone after Stop(false)");
ShutdownThisAppDomainOnce();
return;
}
// if not everything shutdown synchronously give it some time.
int shutdownTimeoutSeconds = HostingEnvironmentSection.DefaultShutdownTimeout;
HostingEnvironmentSection hostEnvConfig = RuntimeConfig.GetAppLKGConfig().HostingEnvironment;
if (hostEnvConfig != null) {
shutdownTimeoutSeconds = (int) hostEnvConfig.ShutdownTimeout.TotalSeconds;
}
Debug.Trace("HostingEnvironmentShutdown", "Waiting for " + shutdownTimeoutSeconds + " sec...");
DateTime waitUntil = DateTime.UtcNow.AddSeconds(shutdownTimeoutSeconds);
while (_registeredObjects.Count > 0 && DateTime.UtcNow < waitUntil) {
Thread.Sleep(100);
}
Debug.Trace("HostingEnvironmentShutdown", "Shutdown timeout (" + shutdownTimeoutSeconds + " sec) expired");
// call Stop on all registered objects with immediate = true
StopRegisteredObjects(true);
// no registered objects -- shutdown now
if (_registeredObjects.Count == 0) {
Debug.Trace("HostingEnvironmentShutdown", "All registered objects gone after Stop(true)");
ShutdownThisAppDomainOnce();
return;
}
// shutdown regardless
Debug.Trace("HostingEnvironmentShutdown", "Forced shutdown: " + _registeredObjects.Count + " registered objects left");
_registeredObjects = new Hashtable();
ShutdownThisAppDomainOnce();
}
// app domain shutdown logic
internal void InitiateShutdownInternal() {
Debug.Trace("AppManager", "HostingEnvironment.InitiateShutdownInternal appId=" + _appId);
bool proceed = false;
if (!_shutdownInitated) {
lock (this) {
if (!_shutdownInitated) {
_shutdownInProgress = true;
proceed = true;
_shutdownInitated = true;
}
}
}
if (!proceed) {
return;
}
HttpRuntime.SetShutdownReason(ApplicationShutdownReason.HostingEnvironment, "HostingEnvironment initiated shutdown");
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
try {
_shutDownStack = Environment.StackTrace;
}
finally {
CodeAccessPermission.RevertAssert();
}
RemoveThisAppDomainFromAppManagerTableOnce();
// stop all registered objects without blocking
ThreadPool.QueueUserWorkItem(this._initiateShutdownWorkItemCallback);
}
internal bool HasBeenRemovedFromAppManagerTable {
get {
return _hasBeenRemovedFromAppManangerTable;
}
set {
_hasBeenRemovedFromAppManangerTable = value;
}
}
private void RemoveThisAppDomainFromAppManagerTableOnce() {
bool proceed = false;
if (!_removedFromAppManager) {
lock (this) {
if (!_removedFromAppManager) {
proceed = true;
_removedFromAppManager = true;
}
}
}
if (!proceed)
return;
if (_appManager != null) {
Debug.Trace("AppManager", "Removing HostingEnvironment from AppManager table, appId=" + _appId);
_appManager.HostingEnvironmentShutdownInitiated(_appId, this);
}
}
private void ShutdownThisAppDomainOnce() {
bool proceed = false;
if (!_appDomainShutdownStarted) {
lock (this) {
if (!_appDomainShutdownStarted) {
proceed = true;
_appDomainShutdownStarted = true;
}
}
}
if (!proceed)
return;
Debug.Trace("AppManager", "HostingEnvironment - shutting down AppDomain, appId=" + _appId);
// stop the timer used for idle timeout
if (_idleTimeoutMonitor != null) {
_idleTimeoutMonitor.Stop();
_idleTimeoutMonitor = null;
}
//
HttpRuntime.SetUserForcedShutdown();
//WOS 1400290: CantUnloadAppDomainException in ISAPI mode, wait until HostingEnvironment.ShutdownThisAppDomainOnce completes
_shutdownInProgress = false;
HttpRuntime.ShutdownAppDomainWithStackTrace(ApplicationShutdownReason.HostingEnvironment,
SR.GetString(SR.Hosting_Env_Restart),
_shutDownStack);
}
//
// internal methods called by app manager
//
// helper for app manager to implement AppHost.CreateAppHost
internal ObjectHandle CreateInstance(Type type) {
return new ObjectHandle(Activator.CreateInstance(type));
}
// start well known object
internal ObjectHandle CreateWellKnownObjectInstance(Type type, bool failIfExists) {
IRegisteredObject obj = null;
String key = type.FullName;
bool exists = false;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
if (obj == null) {
obj = (IRegisteredObject)Activator.CreateInstance(type);
_wellKnownObjects[key] = obj;
}
else {
exists = true;
}
}
if (exists && failIfExists) {
throw new InvalidOperationException(SR.GetString(SR.Wellknown_object_already_exists, key));
}
return new ObjectHandle(obj);
}
// check if well known object
private bool IsWellKnownObject(Object obj) {
bool found = false;
String key = obj.GetType().FullName;
lock (this) {
if (_wellKnownObjects[key] == obj) {
found = true;
}
}
return found;
}
// find well known object by type
internal ObjectHandle FindWellKnownObject(Type type) {
IRegisteredObject obj = null;
String key = type.FullName;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
}
return (obj != null) ? new ObjectHandle(obj) : null;
}
// stop well known object by type
internal void StopWellKnownObject(Type type) {
IRegisteredObject obj = null;
String key = type.FullName;
lock (this) {
obj = _wellKnownObjects[key] as IRegisteredObject;
if (obj != null) {
_wellKnownObjects.Remove(key);
obj.Stop(false);
}
}
}
internal bool IsIdle() {
bool isBusy = _isBusy;
_isBusy = false;
return (!isBusy && _busyCount == 0);
}
internal bool GetIdleValue() {
return (!_isBusy && _busyCount == 0);
}
internal void IncrementBusyCountInternal() {
_isBusy = true;
Interlocked.Increment(ref _busyCount);
}
internal void DecrementBusyCountInternal() {
_isBusy = true;
Interlocked.Decrement(ref _busyCount);
// Notify idle timeout monitor
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm != null) {
itm.LastEvent = DateTime.UtcNow;
}
}
internal void IsUnloaded()
{
return;
}
private void MessageReceivedInternal() {
_isBusy = true;
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm != null) {
itm.LastEvent = DateTime.UtcNow;
}
}
// the busier the app domain the higher the score
internal int LruScore {
get {
if (_busyCount > 0)
return _busyCount;
IdleTimeoutMonitor itm = _idleTimeoutMonitor;
if (itm == null)
return 0;
// return negative number of seconds since last activity
return -(int)(DateTime.UtcNow - itm.LastEvent).TotalSeconds;
}
}
internal static ApplicationManager GetApplicationManager() {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appManager;
}
//
// private helpers
//
// register protocol handler with hosting environment
private void RegisterRunningObjectInternal(IRegisteredObject obj) {
lock (this) {
_registeredObjects[obj] = obj;
}
}
// unregister protocol handler from hosting environment
private void UnregisterRunningObjectInternal(IRegisteredObject obj) {
bool lastOne = false;
lock (this) {
// if it is a well known object, remove it from that table as well
String key = obj.GetType().FullName;
if (_wellKnownObjects[key] == obj) {
_wellKnownObjects.Remove(key);
}
// remove from running objects list
_registeredObjects.Remove(obj);
if (_registeredObjects.Count == 0)
lastOne = true;
}
if (!lastOne)
return;
// shutdown app domain after last protocol handler is gone
InitiateShutdownInternal();
}
// site name
private String GetSiteName() {
if (_siteName == null) {
lock (this) {
if (_siteName == null) {
String s = null;
if (_appHost != null) {
//
InternalSecurityPermissions.Unrestricted.Assert();
try {
s = _appHost.GetSiteName();
}
finally {
CodeAccessPermission.RevertAssert();
}
}
if (s == null)
s = WebConfigurationHost.DefaultSiteName;
_siteName = s;
}
}
}
return _siteName;
}
// site ID
private String GetSiteID() {
if (_siteID == null) {
lock (this) {
if (_siteID == null) {
String s = null;
if (_appHost != null) {
//
InternalSecurityPermissions.Unrestricted.Assert();
try {
s = _appHost.GetSiteID();
}
finally {
CodeAccessPermission.RevertAssert();
}
}
if (s == null)
s = WebConfigurationHost.DefaultSiteID;
_siteID = s.ToLower(CultureInfo.InvariantCulture);
}
}
}
return _siteID;
}
// Return the configPath for the app, e.g. "machine/webroot/1/myapp"
private String GetAppConfigPath() {
if (_appConfigPath == null) {
_appConfigPath = WebConfigurationHost.GetConfigPathFromSiteIDAndVPath(SiteID, ApplicationVirtualPathObject);
}
return _appConfigPath;
}
// Return the call context slot name to use for a virtual path
private static string GetFixedMappingSlotName(VirtualPath virtualPath) {
return "MapPath_" + virtualPath.VirtualPathString.ToLowerInvariant().GetHashCode().ToString(CultureInfo.InvariantCulture);
}
/*
* Map a virtual path to a physical path. i.e. the physicalPath will be returned
* when MapPath is called on the virtual path, bypassing the IApplicationHost
*/
private static string GetVirtualPathToFileMapping(VirtualPath virtualPath) {
return CallContext.GetData(GetFixedMappingSlotName(virtualPath)) as string;
}
/*
* Map a virtual path to a physical path. i.e. the physicalPath will be returned
* when MapPath is called on the virtual path, bypassing the IApplicationHost
*/
internal static object AddVirtualPathToFileMapping(
VirtualPath virtualPath, string physicalPath) {
// Save the mapping in the call context, using a key derived from the
// virtual path. The mapping is only valid for the duration of the request.
CallContext.SetData(GetFixedMappingSlotName(virtualPath), physicalPath);
// Return a mapping object to keep track of the virtual path, and of the current
// virtualPathProvider.
VirtualPathToFileMappingState state = new VirtualPathToFileMappingState();
state.VirtualPath = virtualPath;
state.VirtualPathProvider = _theHostingEnvironment._virtualPathProvider;
// Always use the MapPathBasedVirtualPathProvider, otherwise the mapping mechanism
// doesn't work (VSWhidbey 420702)
_theHostingEnvironment._virtualPathProvider = _theHostingEnvironment._mapPathBasedVirtualPathProvider;
return state;
}
internal static void ClearVirtualPathToFileMapping(object state) {
VirtualPathToFileMappingState mapping = (VirtualPathToFileMappingState)state;
// Clear the mapping from the call context
CallContext.SetData(GetFixedMappingSlotName(mapping.VirtualPath), null);
// Restore the previous VirtualPathProvider
_theHostingEnvironment._virtualPathProvider = mapping.VirtualPathProvider;
}
private string MapPathActual(VirtualPath virtualPath, bool permitNull)
{
string result = null;
Debug.Assert(virtualPath != null);
virtualPath.FailIfRelativePath();
VirtualPath reqpath = virtualPath;
if (String.CompareOrdinal(reqpath.VirtualPathString, _appVirtualPath.VirtualPathString) == 0) {
// for application path don't need to call app host
Debug.Trace("MapPath", reqpath +" is the app path");
result = _appPhysicalPath;
}
else {
using (new ProcessImpersonationContext()) {
// If there is a mapping for this virtual path in the call context, use it
result = GetVirtualPathToFileMapping(reqpath);
if (result == null) {
// call host's mappath
if (_configMapPath == null) {
Debug.Trace("MapPath", "Missing _configMapPath");
throw new InvalidOperationException(SR.GetString(SR.Cannot_map_path, reqpath));
}
Debug.Trace("MapPath", "call ConfigMapPath (" + reqpath + ")");
// see if the IConfigMapPath provider implements the interface
// with VirtualPath
if (null != _configMapPath2) {
result = _configMapPath2.MapPath(GetSiteID(), reqpath);
}
else {
result = _configMapPath.MapPath(GetSiteID(), reqpath.VirtualPathString);
}
}
}
}
if (String.IsNullOrEmpty(result)) {
Debug.Trace("MapPath", "null Result");
if (!permitNull) {
throw new InvalidOperationException(SR.GetString(SR.Cannot_map_path, reqpath));
}
}
else {
// ensure extra '\\' in the physical path if the virtual path had extra '/'
// and the other way -- no extra '\\' in physical if virtual didn't have it.
if (virtualPath.HasTrailingSlash) {
if (!UrlPath.PathEndsWithExtraSlash(result) && !UrlPath.PathIsDriveRoot(result))
result = result + "\\";
}
else {
if (UrlPath.PathEndsWithExtraSlash(result) && !UrlPath.PathIsDriveRoot(result))
result = result.Substring(0, result.Length - 1);
}
Debug.Trace("MapPath", " result=" + result);
}
return result;
}
//
// public static methods
//
// register protocol handler with hosting environment
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void RegisterObject(IRegisteredObject obj) {
if (_theHostingEnvironment != null)
_theHostingEnvironment.RegisterRunningObjectInternal(obj);
}
// unregister protocol handler from hosting environment
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void UnregisterObject(IRegisteredObject obj) {
if (_theHostingEnvironment != null)
_theHostingEnvironment.UnregisterRunningObjectInternal(obj);
}
//
// public static methods for the user code to call
//
public static void IncrementBusyCount() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.IncrementBusyCountInternal();
}
public static void DecrementBusyCount() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.DecrementBusyCountInternal();
}
public static void MessageReceived() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.MessageReceivedInternal();
}
public static bool IsHosted {
get {
return (_theHostingEnvironment != null);
}
}
internal static bool IsUnderIISProcess {
get {
String process = VersionInfo.ExeName;
return process == "aspnet_wp" ||
process == "w3wp" ||
process == "inetinfo";
}
}
internal static bool IsUnderIIS6Process {
get {
return VersionInfo.ExeName == "w3wp";
}
}
public static IApplicationHost ApplicationHost {
//DevDivBugs 109864: ASP.NET: path discovery issue - In low trust, it is possible to get the physical path of any virtual path on the machine
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appHost;
}
}
internal IApplicationHost InternalApplicationHost {
get {
return _appHost;
}
}
internal static int BusyCount {
get {
if (_theHostingEnvironment == null)
return 0;
return _theHostingEnvironment._busyCount;
}
}
internal static bool ShutdownInitiated {
get {
if (_theHostingEnvironment == null)
return false;
return _theHostingEnvironment._shutdownInitated;
}
}
internal static bool ShutdownInProgress {
get {
if (_theHostingEnvironment == null)
return false;
return _theHostingEnvironment._shutdownInProgress;
}
}
///
/// The application ID (metabase path in IIS hosting).
///
public static String ApplicationID {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AspNetHostingPermissionLevelHigh.Demand();
return _theHostingEnvironment._appId;
}
}
internal static String ApplicationIDNoDemand {
get {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment._appId;
}
}
///
/// Physical path to the application root.
///
public static String ApplicationPhysicalPath {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AppPathDiscovery.Demand();
return _theHostingEnvironment._appPhysicalPath;
}
}
///
/// Virtual path to the application root.
///
public static String ApplicationVirtualPath {
get {
return VirtualPath.GetVirtualPathStringNoTrailingSlash(ApplicationVirtualPathObject);
}
}
internal static VirtualPath ApplicationVirtualPathObject {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._appVirtualPath;
}
}
///
/// Site name.
///
public static String SiteName {
get {
if (_theHostingEnvironment == null)
return null;
InternalSecurityPermissions.AspNetHostingPermissionLevelMedium.Demand();
return _theHostingEnvironment.GetSiteName();
}
}
internal static String SiteNameNoDemand {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment.GetSiteName();
}
}
internal static String SiteID {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment.GetSiteID();
}
}
internal static IConfigMapPath ConfigMapPath {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._configMapPath;
}
}
internal static String AppConfigPath {
get {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.GetAppConfigPath();
}
}
///
///
/// Gets a reference to the System.Web.Cache.Cache object for the current request.
///
///
public static Cache Cache {
get { return HttpRuntime.Cache; }
}
// count of all app domain from app manager
internal static int AppDomainsCount {
get {
ApplicationManager appManager = GetApplicationManager();
return (appManager != null) ? appManager.AppDomainsCount : 0;
}
}
internal static HostingEnvironmentParameters HostingParameters {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._hostingParameters;
}
}
// Return an integer that is unique for each appdomain. This can be used
// to create things like once-per-appdomain temp files without having different
// processes/appdomains step on each other
private static int s_appDomainUniqueInteger;
internal static int AppDomainUniqueInteger {
get {
if (s_appDomainUniqueInteger == 0) {
s_appDomainUniqueInteger = Guid.NewGuid().GetHashCode();
}
return s_appDomainUniqueInteger;
}
}
public static ApplicationShutdownReason ShutdownReason {
get { return HttpRuntime.ShutdownReason; }
}
///
/// Initiate app domain unloading for the current app.
///
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static void InitiateShutdown() {
if (_theHostingEnvironment != null)
_theHostingEnvironment.InitiateShutdownInternal();
}
///
/// Maps a virtual path to a physical path.
///
public static string MapPath(string virtualPath) {
return MapPath(VirtualPath.Create(virtualPath));
}
internal static string MapPath(VirtualPath virtualPath) {
if (_theHostingEnvironment == null)
return null;
String path = MapPathInternal(virtualPath);
if (path != null)
InternalSecurityPermissions.PathDiscovery(path).Demand();
return path;
}
internal static String MapPathInternal(string virtualPath) {
return MapPathInternal(VirtualPath.Create(virtualPath));
}
internal static String MapPathInternal(VirtualPath virtualPath) {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.MapPathActual(virtualPath, false);
}
internal static String MapPathInternal(string virtualPath, bool permitNull) {
return MapPathInternal(VirtualPath.Create(virtualPath), permitNull);
}
internal static String MapPathInternal(VirtualPath virtualPath, bool permitNull) {
if (_theHostingEnvironment == null) {
return null;
}
return _theHostingEnvironment.MapPathActual(virtualPath, permitNull);
}
internal static string MapPathInternal(string virtualPath, string baseVirtualDir, bool allowCrossAppMapping) {
return MapPathInternal(VirtualPath.Create(virtualPath),
VirtualPath.CreateNonRelative(baseVirtualDir), allowCrossAppMapping);
}
internal static string MapPathInternal(VirtualPath virtualPath, VirtualPath baseVirtualDir, bool allowCrossAppMapping) {
Debug.Assert(baseVirtualDir != null, "baseVirtualDir != null");
// Combine it with the base and reduce
virtualPath = baseVirtualDir.Combine(virtualPath);
if (!allowCrossAppMapping && !virtualPath.IsWithinAppRoot)
throw new ArgumentException(SR.GetString(SR.Cross_app_not_allowed, virtualPath));
return MapPathInternal(virtualPath);
}
internal static WebApplicationLevel GetPathLevel(String path) {
WebApplicationLevel pathLevel = WebApplicationLevel.AboveApplication;
if (_theHostingEnvironment != null && !String.IsNullOrEmpty(path)) {
String appPath = ApplicationVirtualPath;
if (appPath == "/") {
if (path == "/") {
pathLevel = WebApplicationLevel.AtApplication;
}
else if (path[0] == '/') {
pathLevel = WebApplicationLevel.BelowApplication;
}
}
else {
if (StringUtil.EqualsIgnoreCase(appPath, path)) {
pathLevel = WebApplicationLevel.AtApplication;
}
else if (path.Length > appPath.Length && path[appPath.Length] == '/' &&
StringUtil.StringStartsWithIgnoreCase(path, appPath)) {
pathLevel = WebApplicationLevel.BelowApplication;
}
}
}
return pathLevel;
}
//
// Impersonation helpers
//
// user token for the app (hosting / unc)
internal static IntPtr ApplicationIdentityToken {
get {
if (_theHostingEnvironment == null) {
return IntPtr.Zero;
}
else {
if (_theHostingEnvironment._appIdentityTokenSet)
return _theHostingEnvironment._appIdentityToken;
else
return _theHostingEnvironment._configToken;
}
}
}
// check if application impersonation != process impersonation
internal static bool HasHostingIdentity {
get {
return (ApplicationIdentityToken != IntPtr.Zero);
}
}
// impersonate application identity
[SecurityPermission(SecurityAction.Demand, ControlPrincipal = true)]
public static IDisposable Impersonate() {
return new ApplicationImpersonationContext();
}
// impersonate the given user identity
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static IDisposable Impersonate(IntPtr token) {
if (token == IntPtr.Zero) {
return new ProcessImpersonationContext();
}
else {
return new ImpersonationContext(token);
}
}
// impersonate as configured for a given path
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
public static IDisposable Impersonate(IntPtr userToken, String virtualPath) {
virtualPath = UrlPath.MakeVirtualPathAppAbsoluteReduceAndCheck(virtualPath);
if (_theHostingEnvironment == null) {
return Impersonate(userToken);
}
IdentitySection c = RuntimeConfig.GetConfig(virtualPath).Identity;
if (c.Impersonate) {
if (c.ImpersonateToken != IntPtr.Zero) {
return new ImpersonationContext(c.ImpersonateToken);
}
else {
return new ImpersonationContext(userToken);
}
}
else {
return new ApplicationImpersonationContext();
}
}
//
// Culture helpers
//
public static IDisposable SetCultures() {
return SetCultures(RuntimeConfig.GetAppLKGConfig().Globalization);
}
public static IDisposable SetCultures(string virtualPath) {
virtualPath = UrlPath.MakeVirtualPathAppAbsoluteReduceAndCheck(virtualPath);
return SetCultures(RuntimeConfig.GetConfig(virtualPath).Globalization);
}
private static IDisposable SetCultures(GlobalizationSection gs) {
CultureContext c = new CultureContext();
if (gs != null) {
CultureInfo culture = null;
CultureInfo uiCulture = null;
if (gs.Culture != null && gs.Culture.Length > 0) {
try {
culture = HttpServerUtility.CreateReadOnlyCultureInfo(gs.Culture);
}
catch {
}
}
if (gs.UICulture != null && gs.UICulture.Length > 0) {
try {
uiCulture = HttpServerUtility.CreateReadOnlyCultureInfo(gs.UICulture);
}
catch {
}
}
c.SetCultures(culture, uiCulture);
}
return c;
}
class CultureContext : IDisposable {
CultureInfo _savedCulture;
CultureInfo _savedUICulture;
internal CultureContext() {
}
void IDisposable.Dispose() {
RestoreCultures();
}
internal void SetCultures(CultureInfo culture, CultureInfo uiCulture) {
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
if (culture != null && culture != currentCulture) {
Thread.CurrentThread.CurrentCulture = culture;
_savedCulture = currentCulture;
}
if (uiCulture != null && uiCulture != currentCulture) {
Thread.CurrentThread.CurrentUICulture = uiCulture;
_savedUICulture = currentUICulture;
}
}
internal void RestoreCultures() {
if (_savedCulture != null && _savedCulture != Thread.CurrentThread.CurrentCulture) {
Thread.CurrentThread.CurrentCulture = _savedCulture;
_savedCulture = null;
}
if (_savedUICulture != null && _savedUICulture != Thread.CurrentThread.CurrentUICulture) {
Thread.CurrentThread.CurrentUICulture = _savedUICulture;
_savedUICulture = null;
}
}
}
//
// VirtualPathProvider related code
//
private VirtualPathProvider _virtualPathProvider;
private VirtualPathProvider _mapPathBasedVirtualPathProvider;
public static VirtualPathProvider VirtualPathProvider {
get {
if (_theHostingEnvironment == null)
return null;
return _theHostingEnvironment._virtualPathProvider;
}
}
internal static bool UsingMapPathBasedVirtualPathProvider {
get {
if (_theHostingEnvironment == null)
return true;
return (_theHostingEnvironment._virtualPathProvider ==
_theHostingEnvironment._mapPathBasedVirtualPathProvider);
}
}
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
public static void RegisterVirtualPathProvider(VirtualPathProvider virtualPathProvider) {
if (_theHostingEnvironment == null)
throw new InvalidOperationException();
// Ignore the VirtualPathProvider on precompiled sites (VSWhidbey 368169,404844)
if (BuildManager.IsPrecompiledApp)
return;
RegisterVirtualPathProviderInternal(virtualPathProvider);
}
internal static void RegisterVirtualPathProviderInternal(VirtualPathProvider virtualPathProvider) {
VirtualPathProvider previous = _theHostingEnvironment._virtualPathProvider;
_theHostingEnvironment._virtualPathProvider = virtualPathProvider;
// Give it the previous provider so it can delegate if needed
virtualPathProvider.Initialize(previous);
}
// Helper class used to keep track of state when using
// AddVirtualPathToFileMapping & ClearVirtualPathToFileMapping
internal class VirtualPathToFileMappingState {
internal VirtualPath VirtualPath;
internal VirtualPathProvider VirtualPathProvider;
}
internal static IProcessHostSupportFunctions SupportFunctions {
get {
return _functions;
}
set {
_functions = value;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SizeConverter.cs
- WebServiceClientProxyGenerator.cs
- ReadingWritingEntityEventArgs.cs
- ItemType.cs
- PrivilegeNotHeldException.cs
- ModelVisual3D.cs
- CompilerTypeWithParams.cs
- AssociationSetEnd.cs
- CompiledRegexRunner.cs
- Environment.cs
- nulltextnavigator.cs
- ParallelTimeline.cs
- QuaternionValueSerializer.cs
- FileSecurity.cs
- XmlSchemaDocumentation.cs
- WizardSideBarListControlItem.cs
- sitestring.cs
- WebPartZoneCollection.cs
- Switch.cs
- SQLDoubleStorage.cs
- XmlValidatingReader.cs
- QilTernary.cs
- OletxVolatileEnlistment.cs
- InputLanguageManager.cs
- Themes.cs
- Substitution.cs
- CachedRequestParams.cs
- SynchronousChannel.cs
- BinHexEncoder.cs
- Pair.cs
- EnumValidator.cs
- ObjectHelper.cs
- DataBoundControlHelper.cs
- SafeNativeMethodsCLR.cs
- PassportPrincipal.cs
- FrameDimension.cs
- ClusterRegistryConfigurationProvider.cs
- DataGridViewRowCollection.cs
- FileVersion.cs
- VirtualPathUtility.cs
- ManifestSignedXml.cs
- PriorityQueue.cs
- GifBitmapEncoder.cs
- XmlSchemaSubstitutionGroup.cs
- processwaithandle.cs
- DragDrop.cs
- CommandID.cs
- FlowPosition.cs
- XmlSchemaComplexContentExtension.cs
- XPathNodeIterator.cs
- DataGridRelationshipRow.cs
- TextTrailingWordEllipsis.cs
- FusionWrap.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- ZoneLinkButton.cs
- HighlightComponent.cs
- ECDiffieHellmanPublicKey.cs
- ConditionValidator.cs
- TreeNodeBinding.cs
- FormDocumentDesigner.cs
- ConfigXmlWhitespace.cs
- TCEAdapterGenerator.cs
- NativeMethods.cs
- BStrWrapper.cs
- AnnotationResourceCollection.cs
- SafeReadContext.cs
- RowToParametersTransformer.cs
- ParallelTimeline.cs
- CallbackValidatorAttribute.cs
- SectionInformation.cs
- DockAndAnchorLayout.cs
- ListViewInsertEventArgs.cs
- AssertFilter.cs
- SymbolDocumentInfo.cs
- StackBuilderSink.cs
- DirectoryNotFoundException.cs
- InitializationEventAttribute.cs
- UrlMappingCollection.cs
- XPathNodeIterator.cs
- InProcStateClientManager.cs
- BuilderElements.cs
- PageAction.cs
- CodePrimitiveExpression.cs
- mediaeventshelper.cs
- ConfigurationStrings.cs
- DropTarget.cs
- TypeHelper.cs
- BinaryWriter.cs
- SafeHandles.cs
- PromptStyle.cs
- XmlSerializer.cs
- ListItemConverter.cs
- DependencyPropertyKey.cs
- CookieHandler.cs
- DropShadowBitmapEffect.cs
- ScriptingSectionGroup.cs
- _AutoWebProxyScriptHelper.cs
- PrivilegeNotHeldException.cs
- DbProviderFactoriesConfigurationHandler.cs
- ConvertTextFrag.cs