1 //------------------------------------------------------------------------------ 2 // <copyright file="ISAPIApplicationHost.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 /* 8 * Application host for IIS 5.0 and 6.0 9 * 10 * Copyright (c) 1999 Microsoft Corporation 11 */ 12 13 namespace System.Web.Hosting { 14 using Microsoft.Win32; 15 using System.IO; 16 using System.Text; 17 using System.Web; 18 using System.Web.Configuration; 19 using System.Web.Util; 20 using System.Web.Management; 21 using System.Diagnostics.CodeAnalysis; 22 23 24 // helper class to implement AppHost based on ISAPI 25 internal class ISAPIApplicationHost : MarshalByRefObject, IApplicationHost { 26 private String _appId; 27 private String _siteID; 28 private String _siteName; 29 private VirtualPath _virtualPath; 30 private String _physicalPath; 31 private IProcessHostSupportFunctions _functions; 32 private String _iisVersion; 33 34 private const int MAX_PATH = 260; 35 private const string LMW3SVC_PREFIX = "/LM/W3SVC/"; 36 private const string DEFAULT_SITEID = "1"; 37 private const string DEFAULT_APPID_PREFIX = "/LM/W3SVC/1/ROOT"; 38 ISAPIApplicationHost(string appIdOrVirtualPath, string physicalPath, bool validatePhysicalPath, IProcessHostSupportFunctions functions, string iisVersion = null)39 internal ISAPIApplicationHost(string appIdOrVirtualPath, string physicalPath, bool validatePhysicalPath, IProcessHostSupportFunctions functions, string iisVersion = null) { 40 _iisVersion = iisVersion; 41 // appIdOrVirtualPath is either a full metabase path, or just a virtual path 42 // e.g. /LM/W3SVC/1/Root/MyApp ot /MyApp 43 // Figure out which one we have, and get the other one from it 44 _functions = functions; 45 46 // make sure the functions are set in the default domain 47 if (null == _functions) { 48 ProcessHost h = ProcessHost.DefaultHost; 49 50 if (null != h) { 51 _functions = h.SupportFunctions; 52 53 if (null != _functions) { 54 HostingEnvironment.SupportFunctions = _functions; 55 } 56 } 57 } 58 59 IServerConfig serverConfig = ServerConfig.GetDefaultDomainInstance(_iisVersion); 60 61 if (StringUtil.StringStartsWithIgnoreCase(appIdOrVirtualPath, LMW3SVC_PREFIX)) { 62 _appId = appIdOrVirtualPath; 63 _virtualPath = VirtualPath.Create(ExtractVPathFromAppId(_appId)); 64 _siteID = ExtractSiteIdFromAppId(_appId); 65 _siteName = serverConfig.GetSiteNameFromSiteID(_siteID); 66 } 67 else { 68 _virtualPath = VirtualPath.Create(appIdOrVirtualPath); 69 _appId = GetDefaultAppIdFromVPath(_virtualPath.VirtualPathString); 70 _siteID = DEFAULT_SITEID; 71 _siteName = serverConfig.GetSiteNameFromSiteID(_siteID); 72 } 73 74 // Get the physical path from the virtual path if it wasn't passed in 75 if (physicalPath == null) { 76 _physicalPath = serverConfig.MapPath(this, _virtualPath); 77 } 78 else { 79 _physicalPath = physicalPath; 80 } 81 82 if (validatePhysicalPath) { 83 if (!Directory.Exists(_physicalPath)) { 84 throw new HttpException(SR.GetString(SR.Invalid_IIS_app, appIdOrVirtualPath)); 85 } 86 } 87 } 88 ISAPIApplicationHost(string appIdOrVirtualPath, string physicalPath, bool validatePhysicalPath)89 internal ISAPIApplicationHost(string appIdOrVirtualPath, string physicalPath, bool validatePhysicalPath) 90 :this(appIdOrVirtualPath, physicalPath, validatePhysicalPath, null) 91 {} 92 InitializeLifetimeService()93 public override Object InitializeLifetimeService() { 94 return null; // never expire lease 95 } 96 97 // IApplicationHost implementation IApplicationHost.GetVirtualPath()98 string IApplicationHost.GetVirtualPath() { 99 return _virtualPath.VirtualPathString; 100 } 101 IApplicationHost.GetPhysicalPath()102 String IApplicationHost.GetPhysicalPath() { 103 return _physicalPath; 104 } 105 IApplicationHost.GetConfigMapPathFactory()106 IConfigMapPathFactory IApplicationHost.GetConfigMapPathFactory() { 107 return new ISAPIConfigMapPathFactory(); 108 } 109 IApplicationHost.GetConfigToken()110 IntPtr IApplicationHost.GetConfigToken() { 111 if (null != _functions) { 112 return _functions.GetConfigToken(_appId); 113 } 114 IntPtr token = IntPtr.Zero; 115 116 String username; 117 String password; 118 IServerConfig serverConfig = ServerConfig.GetDefaultDomainInstance(_iisVersion); 119 bool hasUncUser = serverConfig.GetUncUser(this, _virtualPath, out username, out password); 120 if (hasUncUser) { 121 try { 122 String error; 123 token = IdentitySection.CreateUserToken(username, password, out error); 124 } 125 catch { 126 } 127 } 128 129 return token; 130 } 131 IApplicationHost.GetSiteName()132 String IApplicationHost.GetSiteName() { 133 return _siteName; 134 } 135 IApplicationHost.GetSiteID()136 String IApplicationHost.GetSiteID() { 137 return _siteID; 138 } 139 IApplicationHost.MessageReceived()140 void IApplicationHost.MessageReceived() { 141 // make this method call a no-op 142 // it will be removed soon altogether 143 } 144 145 internal string AppId { 146 get { return _appId; } 147 } 148 ExtractVPathFromAppId(string id)149 private static String ExtractVPathFromAppId(string id) { 150 // app id is /LM/W3SVC/1/ROOT for root or /LM/W3SVC/1/ROOT/VDIR 151 152 // find fifth / (assuming it starts with /) 153 int si = 0; 154 for (int i = 1; i < 5; i++) { 155 si = id.IndexOf('/', si+1); 156 if (si < 0) 157 break; 158 } 159 160 if (si < 0) // root? 161 return "/"; 162 else 163 return id.Substring(si); 164 } 165 GetDefaultAppIdFromVPath(string virtualPath)166 private static String GetDefaultAppIdFromVPath(string virtualPath) { 167 if (virtualPath.Length == 1 && virtualPath[0] == '/') { 168 return DEFAULT_APPID_PREFIX; 169 } 170 else { 171 return DEFAULT_APPID_PREFIX + virtualPath; 172 } 173 } 174 ExtractSiteIdFromAppId(string id)175 private static String ExtractSiteIdFromAppId(string id) { 176 // app id is /LM/W3SVC/1/ROOT for root or /LM/W3SVC/1/ROOT/VDIR 177 // the site id is right after prefix 178 int offset = LMW3SVC_PREFIX.Length; 179 int si = id.IndexOf('/', offset); 180 return (si > 0) ? id.Substring(offset, si - offset) : DEFAULT_SITEID; 181 } 182 183 internal IProcessHostSupportFunctions SupportFunctions { 184 get { 185 return _functions; 186 } 187 } 188 189 [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "This method's caller is trusted.")] ResolveRootWebConfigPath()190 internal string ResolveRootWebConfigPath() { 191 string rootWebConfigPath = null; 192 193 if (null != _functions) { 194 rootWebConfigPath = _functions.GetRootWebConfigFilename(); 195 } 196 197 return rootWebConfigPath; 198 } 199 200 201 } 202 203 // 204 // Create an instance of IConfigMapPath in the worker appdomain. 205 // By making the class Serializable, the call to IConfigMapPathFactory.Create() 206 // will execute in the worker appdomain. 207 // 208 [Serializable()] 209 internal class ISAPIConfigMapPathFactory : IConfigMapPathFactory { IConfigMapPathFactory.Create(string virtualPath, string physicalPath)210 IConfigMapPath IConfigMapPathFactory.Create(string virtualPath, string physicalPath) { 211 return IISMapPath.GetInstance(); 212 } 213 } 214 } 215