1 // 2 // System.AppDomainSetup.cs 3 // 4 // Authors: 5 // Dietmar Maurer (dietmar@ximian.com) 6 // Sebastien Pouliot <sebastien@ximian.com> 7 // 8 // (C) 2001 Ximian, Inc. http://www.ximian.com 9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) 10 // 11 // Known Problems: 12 // Fix serialization compatibility with MS.NET. 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining 15 // a copy of this software and associated documentation files (the 16 // "Software"), to deal in the Software without restriction, including 17 // without limitation the rights to use, copy, modify, merge, publish, 18 // distribute, sublicense, and/or sell copies of the Software, and to 19 // permit persons to whom the Software is furnished to do so, subject to 20 // the following conditions: 21 // 22 // The above copyright notice and this permission notice shall be 23 // included in all copies or substantial portions of the Software. 24 // 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 // 33 34 using System.Collections.Generic; 35 using System.IO; 36 using System.Runtime.CompilerServices; 37 using System.Runtime.InteropServices; 38 using System.Security; 39 using System.Security.Permissions; 40 using System.Runtime.Serialization.Formatters.Binary; 41 42 using System.Runtime.Hosting; 43 using System.Security.Policy; 44 45 namespace System 46 { 47 [Serializable] 48 [ClassInterface (ClassInterfaceType.None)] 49 [ComVisible (true)] 50 [StructLayout (LayoutKind.Sequential)] 51 #if MOBILE 52 public sealed class AppDomainSetup 53 #else 54 public sealed class AppDomainSetup : IAppDomainSetup 55 #endif 56 { 57 string application_base; 58 string application_name; 59 string cache_path; 60 string configuration_file; 61 string dynamic_base; 62 string license_file; 63 string private_bin_path; 64 string private_bin_path_probe; 65 string shadow_copy_directories; 66 string shadow_copy_files; 67 bool publisher_policy; 68 private bool path_changed; 69 #if MOBILE 70 private int loader_optimization; 71 #else 72 private LoaderOptimization loader_optimization; 73 #endif 74 bool disallow_binding_redirects; 75 bool disallow_code_downloads; 76 77 #if MOBILE 78 object _activationArguments; 79 object domain_initializer; 80 object application_trust; 81 #else 82 private ActivationArguments _activationArguments; 83 AppDomainInitializer domain_initializer; 84 [NonSerialized] 85 ApplicationTrust application_trust; 86 #endif 87 string [] domain_initializer_args; 88 89 bool disallow_appbase_probe; 90 byte [] configuration_bytes; 91 92 byte [] serialized_non_primitives; 93 AppDomainSetup()94 public AppDomainSetup () 95 { 96 } 97 AppDomainSetup(AppDomainSetup setup)98 internal AppDomainSetup (AppDomainSetup setup) 99 { 100 application_base = setup.application_base; 101 application_name = setup.application_name; 102 cache_path = setup.cache_path; 103 configuration_file = setup.configuration_file; 104 dynamic_base = setup.dynamic_base; 105 license_file = setup.license_file; 106 private_bin_path = setup.private_bin_path; 107 private_bin_path_probe = setup.private_bin_path_probe; 108 shadow_copy_directories = setup.shadow_copy_directories; 109 shadow_copy_files = setup.shadow_copy_files; 110 publisher_policy = setup.publisher_policy; 111 path_changed = setup.path_changed; 112 loader_optimization = setup.loader_optimization; 113 disallow_binding_redirects = setup.disallow_binding_redirects; 114 disallow_code_downloads = setup.disallow_code_downloads; 115 _activationArguments = setup._activationArguments; 116 domain_initializer = setup.domain_initializer; 117 application_trust = setup.application_trust; 118 domain_initializer_args = setup.domain_initializer_args; 119 disallow_appbase_probe = setup.disallow_appbase_probe; 120 configuration_bytes = setup.configuration_bytes; 121 } 122 AppDomainSetup(ActivationArguments activationArguments)123 public AppDomainSetup (ActivationArguments activationArguments) 124 { 125 _activationArguments = activationArguments; 126 } 127 AppDomainSetup(ActivationContext activationContext)128 public AppDomainSetup (ActivationContext activationContext) 129 { 130 _activationArguments = new ActivationArguments (activationContext); 131 } 132 GetAppBase(string appBase)133 static string GetAppBase (string appBase) 134 { 135 if (appBase == null) 136 return null; 137 138 int len = appBase.Length; 139 if (len >= 8 && appBase.ToLower ().StartsWith ("file://")) { 140 appBase = appBase.Substring (7); 141 if (Path.DirectorySeparatorChar != '/') 142 appBase = appBase.Replace ('/', Path.DirectorySeparatorChar); 143 } 144 appBase = Path.GetFullPath (appBase); 145 146 if (Path.DirectorySeparatorChar != '/') { 147 bool isExtendedPath = appBase.StartsWith (@"\\?\", StringComparison.Ordinal); 148 if (appBase.IndexOf (':', isExtendedPath ? 6 : 2) != -1) { 149 throw new NotSupportedException ("The given path's format is not supported."); 150 } 151 } 152 153 // validate the path 154 string dir = Path.GetDirectoryName (appBase); 155 if ((dir != null) && (dir.LastIndexOfAny (Path.GetInvalidPathChars ()) >= 0)) { 156 string msg = String.Format (Locale.GetText ("Invalid path characters in path: '{0}'"), appBase); 157 throw new ArgumentException (msg, "appBase"); 158 } 159 160 string fname = Path.GetFileName (appBase); 161 if ((fname != null) && (fname.LastIndexOfAny (Path.GetInvalidFileNameChars ()) >= 0)) { 162 string msg = String.Format (Locale.GetText ("Invalid filename characters in path: '{0}'"), appBase); 163 throw new ArgumentException (msg, "appBase"); 164 } 165 166 return appBase; 167 } 168 169 public string ApplicationBase { 170 get { return GetAppBase (application_base); } 171 set { application_base = value; } 172 } 173 174 public string ApplicationName { 175 get { 176 return application_name; 177 } 178 set { 179 application_name = value; 180 } 181 } 182 183 public string CachePath { 184 get { 185 return cache_path; 186 } 187 set { 188 cache_path = value; 189 } 190 } 191 192 public string ConfigurationFile { 193 get { 194 if (configuration_file == null) 195 return null; 196 if (Path.IsPathRooted(configuration_file)) 197 return configuration_file; 198 if (ApplicationBase == null) 199 throw new MemberAccessException("The ApplicationBase must be set before retrieving this property."); 200 return Path.Combine(ApplicationBase, configuration_file); 201 } 202 set { 203 configuration_file = value; 204 } 205 } 206 207 public bool DisallowPublisherPolicy { 208 get { 209 return publisher_policy; 210 } 211 set { 212 publisher_policy = value; 213 } 214 } 215 216 public string DynamicBase { 217 get { 218 if (dynamic_base == null) 219 return null; 220 221 if (Path.IsPathRooted (dynamic_base)) 222 return dynamic_base; 223 224 if (ApplicationBase == null) 225 throw new MemberAccessException ("The ApplicationBase must be set before retrieving this property."); 226 227 return Path.Combine (ApplicationBase, dynamic_base); 228 } 229 set { 230 if (application_name == null) 231 throw new MemberAccessException ("ApplicationName must be set before the DynamicBase can be set."); 232 uint id = (uint) application_name.GetHashCode (); 233 dynamic_base = Path.Combine (value, id.ToString("x")); 234 } 235 } 236 237 public string LicenseFile { 238 get { 239 return license_file; 240 } 241 set { 242 license_file = value; 243 } 244 } 245 246 [MonoLimitation ("In Mono this is controlled by the --share-code flag")] 247 public LoaderOptimization LoaderOptimization { 248 get { 249 return (LoaderOptimization)loader_optimization; 250 } 251 set { 252 #if MOBILE 253 loader_optimization = (int)value; 254 #else 255 loader_optimization = value; 256 #endif 257 } 258 } 259 260 public string PrivateBinPath { 261 get { 262 return private_bin_path; 263 } 264 set { 265 private_bin_path = value; 266 path_changed = true; 267 } 268 } 269 270 public string PrivateBinPathProbe { 271 get { 272 return private_bin_path_probe; 273 } 274 set { 275 private_bin_path_probe = value; 276 path_changed = true; 277 } 278 } 279 280 public string ShadowCopyDirectories { 281 get { 282 return shadow_copy_directories; 283 } 284 set { 285 shadow_copy_directories = value; 286 } 287 } 288 289 public string ShadowCopyFiles { 290 get { 291 return shadow_copy_files; 292 } 293 set { 294 shadow_copy_files = value; 295 } 296 } 297 298 public bool DisallowBindingRedirects { 299 get { 300 return disallow_binding_redirects; 301 } 302 set { 303 disallow_binding_redirects = value; 304 } 305 } 306 307 public bool DisallowCodeDownload { 308 get { 309 return disallow_code_downloads; 310 } 311 set { 312 disallow_code_downloads = value; 313 } 314 } 315 316 public string TargetFrameworkName { get; set; } 317 318 public ActivationArguments ActivationArguments { 319 get { 320 if (_activationArguments != null) 321 return (ActivationArguments)_activationArguments; 322 DeserializeNonPrimitives (); 323 return (ActivationArguments)_activationArguments; 324 } 325 set { _activationArguments = value; } 326 } 327 328 #if MONO_FEATURE_MULTIPLE_APPDOMAINS 329 [MonoLimitation ("it needs to be invoked within the created domain")] 330 public AppDomainInitializer AppDomainInitializer { 331 get { 332 if (domain_initializer != null) 333 return (AppDomainInitializer)domain_initializer; 334 DeserializeNonPrimitives (); 335 return (AppDomainInitializer)domain_initializer; 336 } 337 set { domain_initializer = value; } 338 } 339 #else 340 [Obsolete ("AppDomainSetup.AppDomainInitializer is not supported on this platform.", true)] 341 public AppDomainInitializer AppDomainInitializer { 342 get { throw new PlatformNotSupportedException ("AppDomainSetup.AppDomainInitializer is not supported on this platform."); } 343 set { throw new PlatformNotSupportedException ("AppDomainSetup.AppDomainInitializer is not supported on this platform."); } 344 } 345 #endif // MONO_FEATURE_MULTIPLE_APPDOMAINS 346 347 348 [MonoLimitation ("it needs to be used to invoke the initializer within the created domain")] 349 public string [] AppDomainInitializerArguments { 350 get { return domain_initializer_args; } 351 set { domain_initializer_args = value; } 352 } 353 354 [MonoNotSupported ("This property exists but not considered.")] 355 public ApplicationTrust ApplicationTrust { 356 get { 357 if (application_trust != null) 358 return (ApplicationTrust)application_trust; 359 DeserializeNonPrimitives (); 360 if (application_trust == null) 361 application_trust = new ApplicationTrust (); 362 return (ApplicationTrust)application_trust; 363 } 364 set { application_trust = value; } 365 } 366 367 [MonoNotSupported ("This property exists but not considered.")] 368 public bool DisallowApplicationBaseProbing { 369 get { return disallow_appbase_probe; } 370 set { disallow_appbase_probe = value; } 371 } 372 373 [MonoNotSupported ("This method exists but not considered.")] GetConfigurationBytes()374 public byte [] GetConfigurationBytes () 375 { 376 return configuration_bytes != null ? configuration_bytes.Clone () as byte [] : null; 377 } 378 379 [MonoNotSupported ("This method exists but not considered.")] SetConfigurationBytes(byte [] value)380 public void SetConfigurationBytes (byte [] value) 381 { 382 configuration_bytes = value; 383 } 384 DeserializeNonPrimitives()385 private void DeserializeNonPrimitives () 386 { 387 lock (this) { 388 if (serialized_non_primitives == null) 389 return; 390 391 BinaryFormatter bf = new BinaryFormatter (); 392 MemoryStream ms = new MemoryStream (serialized_non_primitives); 393 394 object [] arr = (object []) bf.Deserialize (ms); 395 396 _activationArguments = (ActivationArguments) arr [0]; 397 #if MONO_FEATURE_MULTIPLE_APPDOMAINS 398 domain_initializer = (AppDomainInitializer) arr [1]; 399 #endif 400 application_trust = (ApplicationTrust) arr [2]; 401 402 serialized_non_primitives = null; 403 } 404 } 405 SerializeNonPrimitives()406 internal void SerializeNonPrimitives () 407 { 408 object [] arr = new object [3]; 409 410 arr [0] = _activationArguments; 411 arr [1] = domain_initializer; 412 arr [2] = application_trust; 413 414 BinaryFormatter bf = new BinaryFormatter (); 415 MemoryStream ms = new MemoryStream (); 416 417 bf.Serialize (ms, arr); 418 419 serialized_non_primitives = ms.ToArray (); 420 } 421 422 [MonoTODO ("not implemented, does not throw because it's used in testing moonlight")] SetCompatibilitySwitches(IEnumerable<string> switches)423 public void SetCompatibilitySwitches (IEnumerable<string> switches) 424 { 425 } 426 } 427 } 428