e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
252 lines
9.4 KiB
C#
252 lines
9.4 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="ISAPIRuntime.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
/*
|
|
* The ASP.NET runtime services
|
|
*
|
|
* Copyright (c) 1998 Microsoft Corporation
|
|
*/
|
|
|
|
namespace System.Web.Hosting {
|
|
using System.Runtime.InteropServices;
|
|
using System.Collections;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Web;
|
|
using System.Web.Management;
|
|
using System.Web.Util;
|
|
using System.Globalization;
|
|
using System.Security.Permissions;
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
/// <internalonly/>
|
|
[ComImport, Guid("08a2c56f-7c16-41c1-a8be-432917a1a2d1"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
|
public interface IISAPIRuntime {
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
[SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
|
|
void StartProcessing();
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
[SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
|
|
void StopProcessing();
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
[SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
|
|
[return: MarshalAs(UnmanagedType.I4)]
|
|
int ProcessRequest(
|
|
[In]
|
|
IntPtr ecb,
|
|
[In, MarshalAs(UnmanagedType.I4)]
|
|
int useProcessModel);
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
[SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
|
|
void DoGCCollect();
|
|
}
|
|
|
|
// DevDiv #195200: Adding link demands to IISAPIRuntime causes partial trust to stop
|
|
// working. Ideally that type should have been internal, but we can't do that since
|
|
// that would be a breaking API change. So instead we introduce a parallel internal
|
|
// type with a different COM GUID. Existing public methods on ISAPIRuntime will be
|
|
// protected by a link demand, but our native layer will go through this specific
|
|
// interface which can bypass the link demands.
|
|
[ComImport, Guid("15eb8d20-d4ed-4855-a276-91a75a696955"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
|
internal interface IISAPIRuntime2 {
|
|
|
|
void StartProcessing();
|
|
|
|
void StopProcessing();
|
|
|
|
[return: MarshalAs(UnmanagedType.I4)]
|
|
int ProcessRequest([In]IntPtr ecb, [In, MarshalAs(UnmanagedType.I4)]int useProcessModel);
|
|
|
|
void DoGCCollect();
|
|
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
/// <internalonly/>
|
|
public sealed class ISAPIRuntime : MarshalByRefObject, IISAPIRuntime, IISAPIRuntime2, IRegisteredObject {
|
|
|
|
// WARNING: do not modify without making corresponding changes in appdomains.h
|
|
private const int WORKER_REQUEST_TYPE_IN_PROC = 0x0;
|
|
private const int WORKER_REQUEST_TYPE_OOP = 0x1;
|
|
private const int WORKER_REQUEST_TYPE_IN_PROC_VERSION_2 = 0x2;
|
|
|
|
// to control removal from unmanaged table (to it only once)
|
|
private static int _isThisAppDomainRemovedFromUnmanagedTable;
|
|
|
|
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
|
|
public ISAPIRuntime() {
|
|
HostingEnvironment.RegisterObject(this);
|
|
}
|
|
|
|
|
|
public override Object InitializeLifetimeService() {
|
|
return null; // never expire lease
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
public void StartProcessing() {
|
|
Debug.Trace("ISAPIRuntime", "StartProcessing");
|
|
}
|
|
|
|
void IISAPIRuntime2.StartProcessing() {
|
|
StartProcessing();
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
public void StopProcessing() {
|
|
Debug.Trace("ISAPIRuntime", "StopProcessing");
|
|
HostingEnvironment.UnregisterObject(this);
|
|
}
|
|
|
|
void IISAPIRuntime2.StopProcessing() {
|
|
StopProcessing();
|
|
}
|
|
|
|
/*
|
|
* Process one ISAPI request
|
|
*
|
|
* @param ecb ECB
|
|
* @param useProcessModel flag set to true when out-of-process
|
|
*/
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
public int ProcessRequest(IntPtr ecb, int iWRType) {
|
|
IntPtr pHttpCompletion = IntPtr.Zero;
|
|
if (iWRType == WORKER_REQUEST_TYPE_IN_PROC_VERSION_2) {
|
|
pHttpCompletion = ecb;
|
|
ecb = UnsafeNativeMethods.GetEcb(pHttpCompletion);
|
|
}
|
|
ISAPIWorkerRequest wr = null;
|
|
try {
|
|
bool useOOP = (iWRType == WORKER_REQUEST_TYPE_OOP);
|
|
wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
|
|
wr.Initialize();
|
|
|
|
// check if app path matches (need to restart app domain?)
|
|
String wrPath = wr.GetAppPathTranslated();
|
|
String adPath = HttpRuntime.AppDomainAppPathInternal;
|
|
|
|
if (adPath == null ||
|
|
StringUtil.EqualsIgnoreCase(wrPath, adPath)) {
|
|
|
|
HttpRuntime.ProcessRequestNoDemand(wr);
|
|
return 0;
|
|
}
|
|
else {
|
|
// need to restart app domain
|
|
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged,
|
|
SR.GetString(SR.Hosting_Phys_Path_Changed,
|
|
adPath,
|
|
wrPath));
|
|
return 1;
|
|
}
|
|
}
|
|
catch(Exception e) {
|
|
try {
|
|
WebBaseEvent.RaiseRuntimeError(e, this);
|
|
} catch {}
|
|
|
|
// Have we called HSE_REQ_DONE_WITH_SESSION? If so, don't re-throw.
|
|
if (wr != null && wr.Ecb == IntPtr.Zero) {
|
|
if (pHttpCompletion != IntPtr.Zero) {
|
|
UnsafeNativeMethods.SetDoneWithSessionCalled(pHttpCompletion);
|
|
}
|
|
// if this is a thread abort exception, cancel the abort
|
|
if (e is ThreadAbortException) {
|
|
Thread.ResetAbort();
|
|
}
|
|
// IMPORTANT: if this thread is being aborted because of an AppDomain.Unload,
|
|
// the CLR will still throw an AppDomainUnloadedException. The native caller
|
|
// must special case COR_E_APPDOMAINUNLOADED(0x80131014) and not
|
|
// call HSE_REQ_DONE_WITH_SESSION more than once.
|
|
return 0;
|
|
}
|
|
|
|
// re-throw if we have not called HSE_REQ_DONE_WITH_SESSION
|
|
throw;
|
|
}
|
|
}
|
|
|
|
int IISAPIRuntime2.ProcessRequest(IntPtr ecb, int iWRType) {
|
|
return ProcessRequest(ecb, iWRType);
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)] // DevDiv #180492
|
|
public void DoGCCollect() {
|
|
for (int c = 10; c > 0; c--) {
|
|
System.GC.Collect();
|
|
}
|
|
}
|
|
|
|
void IISAPIRuntime2.DoGCCollect() {
|
|
DoGCCollect();
|
|
}
|
|
|
|
|
|
/// <internalonly/>
|
|
void IRegisteredObject.Stop(bool immediate) {
|
|
RemoveThisAppDomainFromUnmanagedTable();
|
|
HostingEnvironment.UnregisterObject(this);
|
|
}
|
|
|
|
|
|
internal static void RemoveThisAppDomainFromUnmanagedTable() {
|
|
if (Interlocked.Exchange(ref _isThisAppDomainRemovedFromUnmanagedTable, 1) != 0) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
String appId = HttpRuntime.AppDomainAppId;
|
|
if (appId != null ) {
|
|
Debug.Trace("ISAPIRuntime", "Calling UnsafeNativeMethods.AppDomainRestart appId=" + appId);
|
|
|
|
UnsafeNativeMethods.AppDomainRestart(appId);
|
|
}
|
|
|
|
HttpRuntime.AddAppDomainTraceMessage(SR.GetString(SR.App_Domain_Restart));
|
|
}
|
|
catch {
|
|
}
|
|
}
|
|
}
|
|
}
|