1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 
7 //
8 // An AppDomainManager gives a hosting application the chance to
9 // participate in the creation and control the settings of new AppDomains.
10 //
11 
12 namespace System {
13     using System.Collections;
14     using System.Globalization;
15     using System.IO;
16     using System.Reflection;
17     using System.Runtime.CompilerServices;
18     using System.Security;
19     using System.Security.Permissions;
20     using System.Security.Policy;
21     using System.Threading;
22 #if FEATURE_CLICKONCE
23     using System.Runtime.Hosting;
24 #endif
25     using System.Runtime.Versioning;
26     using System.Runtime.InteropServices;
27     using System.Diagnostics.Contracts;
28 
29 #if FEATURE_APPDOMAINMANAGER_INITOPTIONS
30     [Flags]
31     [System.Runtime.InteropServices.ComVisible(true)]
32     public enum AppDomainManagerInitializationOptions {
33         None             = 0x0000,
34         RegisterWithHost = 0x0001
35     }
36 #endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
37 
38     [System.Security.SecurityCritical]  // auto-generated_required
39     [System.Runtime.InteropServices.ComVisible(true)]
40 #if !FEATURE_CORECLR
41     [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
42 #endif
43 #if FEATURE_REMOTING
44     public class AppDomainManager : MarshalByRefObject {
45 #else // FEATURE_REMOTING
46     public class AppDomainManager {
47 #endif // FEATURE_REMOTING
AppDomainManager()48         public AppDomainManager () {}
49 #if FEATURE_REMOTING
50         [System.Security.SecurityCritical]  // auto-generated
CreateDomain(string friendlyName, Evidence securityInfo, AppDomainSetup appDomainInfo)51         public virtual AppDomain CreateDomain (string friendlyName,
52                                                Evidence securityInfo,
53                                                AppDomainSetup appDomainInfo) {
54             return CreateDomainHelper(friendlyName, securityInfo, appDomainInfo);
55         }
56 
57         [System.Security.SecurityCritical]  // auto-generated_required
58         [SecurityPermissionAttribute(SecurityAction.Demand, ControlAppDomain = true)]
CreateDomainHelper(string friendlyName, Evidence securityInfo, AppDomainSetup appDomainInfo)59         protected static AppDomain CreateDomainHelper (string friendlyName,
60                                                        Evidence securityInfo,
61                                                        AppDomainSetup appDomainInfo) {
62             if (friendlyName == null)
63                 throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_String"));
64 
65             Contract.EndContractBlock();
66             // If evidence is provided, we check to make sure that is allowed.
67             if (securityInfo != null) {
68                 new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
69 
70                 // Check the evidence to ensure that if it expects a sandboxed domain, it actually gets one.
71                 AppDomain.CheckDomainCreationEvidence(appDomainInfo, securityInfo);
72             }
73 
74             if (appDomainInfo == null) {
75                 appDomainInfo = new AppDomainSetup();
76             }
77 
78             // If there was no specified AppDomainManager for the new domain, default it to being the same
79             // as the current domain's AppDomainManager.
80             if (appDomainInfo.AppDomainManagerAssembly == null || appDomainInfo.AppDomainManagerType == null) {
81                 string inheritedDomainManagerAssembly;
82                 string inheritedDomainManagerType;
83 
84                 AppDomain.CurrentDomain.GetAppDomainManagerType(out inheritedDomainManagerAssembly,
85                                                                 out inheritedDomainManagerType);
86 
87                 if (appDomainInfo.AppDomainManagerAssembly == null) {
88                     appDomainInfo.AppDomainManagerAssembly = inheritedDomainManagerAssembly;
89                 }
90                 if (appDomainInfo.AppDomainManagerType == null) {
91                     appDomainInfo.AppDomainManagerType = inheritedDomainManagerType;
92                 }
93             }
94 
95             // If there was no specified TargetFrameworkName for the new domain, default it to the current domain's.
96             if (appDomainInfo.TargetFrameworkName == null)
97                 appDomainInfo.TargetFrameworkName = AppDomain.CurrentDomain.GetTargetFrameworkName();
98 
99             return AppDomain.nCreateDomain(friendlyName,
100                                            appDomainInfo,
101                                            securityInfo,
102                                            securityInfo == null ? AppDomain.CurrentDomain.InternalEvidence : null,
103                                            AppDomain.CurrentDomain.GetSecurityDescriptor());
104         }
105 #endif // FEATURE_REMOTING
106 
107         [System.Security.SecurityCritical]
InitializeNewDomain(AppDomainSetup appDomainInfo)108         public virtual void InitializeNewDomain (AppDomainSetup appDomainInfo) {
109             // By default, InitializeNewDomain does nothing. AppDomain.CreateAppDomainManager relies on this fact.
110         }
111 
112 #if FEATURE_APPDOMAINMANAGER_INITOPTIONS
113 
114         private AppDomainManagerInitializationOptions m_flags = AppDomainManagerInitializationOptions.None;
115         public AppDomainManagerInitializationOptions InitializationFlags {
116             get {
117                 return m_flags;
118             }
119             set {
120                 m_flags = value;
121             }
122         }
123 #endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
124 
125 #if FEATURE_CLICKONCE
126         private ApplicationActivator m_appActivator = null;
127         public virtual ApplicationActivator ApplicationActivator {
128             get {
129                 if (m_appActivator == null)
130                     m_appActivator = new ApplicationActivator();
131                 return m_appActivator;
132             }
133         }
134 #endif //#if FEATURE_CLICKONCE
135 
136 #if FEATURE_CAS_POLICY
137         public virtual HostSecurityManager HostSecurityManager {
138             get {
139                 return null;
140             }
141         }
142 
143         public virtual HostExecutionContextManager HostExecutionContextManager {
144             get {
145                 // By default, the AppDomainManager returns the HostExecutionContextManager.
146                 return HostExecutionContextManager.GetInternalHostExecutionContextManager();
147             }
148         }
149 #endif // FEATURE_CAS_POLICY
150 
151         [ResourceExposure(ResourceScope.None)]
152         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
GetEntryAssembly(ObjectHandleOnStack retAssembly)153         private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
154 
155         private Assembly m_entryAssembly = null;
156         public virtual Assembly EntryAssembly {
157             [System.Security.SecurityCritical]  // auto-generated
158             get {
159                 // The default AppDomainManager sets the EntryAssembly depending on whether the
160                 // AppDomain is a manifest application domain or not. In the first case, we parse
161                 // the application manifest to find out the entry point assembly and return that assembly.
162                 // In the second case, we maintain the old behavior by calling GetEntryAssembly().
163                 if (m_entryAssembly == null)
164                 {
165 
166 #if FEATURE_CLICKONCE
167                     AppDomain domain = AppDomain.CurrentDomain;
168                     if (domain.IsDefaultAppDomain() && domain.ActivationContext != null) {
169                         ManifestRunner runner = new ManifestRunner(domain, domain.ActivationContext);
170                         m_entryAssembly = runner.EntryAssembly;
171                     } else
172 #endif //#if FEATURE_CLICKONCE
173                     {
174                         RuntimeAssembly entryAssembly = null;
175                         GetEntryAssembly(JitHelpers.GetObjectHandleOnStack(ref entryAssembly));
176                         m_entryAssembly = entryAssembly;
177                     }
178                 }
179                 return m_entryAssembly;
180             }
181         }
182 
183         internal static AppDomainManager CurrentAppDomainManager {
184             [System.Security.SecurityCritical]  // auto-generated
185             get {
186                 return AppDomain.CurrentDomain.DomainManager;
187             }
188         }
189 
CheckSecuritySettings(SecurityState state)190         public virtual bool CheckSecuritySettings (SecurityState state)
191         {
192             return false;
193         }
194 
195 #if FEATURE_APPDOMAINMANAGER_INITOPTIONS
196         [ResourceExposure(ResourceScope.None)]
197         [MethodImplAttribute(MethodImplOptions.InternalCall)]
HasHost()198         private static extern bool HasHost();
199 
200         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
201         [ResourceExposure(ResourceScope.None)]
202         [SecurityCritical]
203         [SuppressUnmanagedCodeSecurity]
RegisterWithHost(IntPtr appDomainManager)204         private static extern void RegisterWithHost(IntPtr appDomainManager);
205 
RegisterWithHost()206         internal void RegisterWithHost() {
207             if (HasHost()) {
208                 IntPtr punkAppDomainManager = IntPtr.Zero;
209 
210                 RuntimeHelpers.PrepareConstrainedRegions();
211                 try {
212                     punkAppDomainManager = Marshal.GetIUnknownForObject(this);
213                     RegisterWithHost(punkAppDomainManager);
214                 }
215                 finally {
216                     if (!punkAppDomainManager.IsNull()) {
217                         Marshal.Release(punkAppDomainManager);
218                     }
219                 }
220             }
221         }
222 #endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
223     }
224 }
225