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