1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 /*============================================================ 7 ** 8 ** File: RemotingConfiguration.cs 9 ** 10 ** Purpose: Classes for interfacing with remoting configuration 11 ** settings 12 ** 13 ** 14 ===========================================================*/ 15 16 using System; 17 using System.Security; 18 using System.Security.Permissions; 19 using System.Runtime.Remoting.Activation; 20 using System.Runtime.Remoting.Contexts; 21 using System.Runtime.CompilerServices; 22 using StackCrawlMark = System.Threading.StackCrawlMark; 23 using System.Runtime.Versioning; 24 using System.Diagnostics.Contracts; 25 26 namespace System.Runtime.Remoting 27 { 28 // Configuration - provides static methods interfacing with 29 // configuration settings. 30 [System.Runtime.InteropServices.ComVisible(true)] 31 public static class RemotingConfiguration 32 { 33 private static volatile bool s_ListeningForActivationRequests = false; 34 35 [System.Security.SecuritySafeCritical] // auto-generated 36 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 37 [ResourceExposure(ResourceScope.Machine)] 38 [ResourceConsumption(ResourceScope.Machine)] 39 [Obsolete("Use System.Runtime.Remoting.RemotingConfiguration.Configure(string fileName, bool ensureSecurity) instead.", false)] Configure(String filename)40 public static void Configure(String filename) 41 { 42 Configure(filename, false/*ensureSecurity*/); 43 } 44 [System.Security.SecuritySafeCritical] // auto-generated 45 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 46 [ResourceExposure(ResourceScope.Machine)] 47 [ResourceConsumption(ResourceScope.Machine)] Configure(String filename, bool ensureSecurity)48 public static void Configure(String filename, bool ensureSecurity) 49 { 50 RemotingConfigHandler.DoConfiguration(filename, ensureSecurity); 51 52 // Set a flag in the VM to mark that remoting is configured 53 // This will enable us to decide if activation for MBR 54 // objects should go through the managed codepath 55 RemotingServices.InternalSetRemoteActivationConfigured(); 56 57 } // Configure 58 59 public static String ApplicationName 60 { 61 get 62 { 63 if (!RemotingConfigHandler.HasApplicationNameBeenSet()) 64 return null; 65 else 66 return RemotingConfigHandler.ApplicationName; 67 } 68 69 [System.Security.SecuritySafeCritical] // auto-generated 70 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 71 set 72 { 73 RemotingConfigHandler.ApplicationName = value; 74 } 75 } // ApplicationName 76 77 78 // The application id is prepended to object uri's. 79 public static String ApplicationId 80 { 81 [System.Security.SecurityCritical] // auto-generated_required 82 get { return Identity.AppDomainUniqueId; } 83 } // ApplicationId 84 85 public static String ProcessId 86 { 87 [System.Security.SecurityCritical] // auto-generated_required 88 get { return Identity.ProcessGuid;} 89 } 90 91 public static CustomErrorsModes CustomErrorsMode 92 { 93 get { return RemotingConfigHandler.CustomErrorsMode; } 94 95 [System.Security.SecuritySafeCritical] // auto-generated 96 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] 97 set 98 { 99 RemotingConfigHandler.CustomErrorsMode = value; 100 } 101 102 } 103 CustomErrorsEnabled(bool isLocalRequest)104 public static bool CustomErrorsEnabled(bool isLocalRequest) 105 { 106 switch (CustomErrorsMode) 107 { 108 case CustomErrorsModes.Off: 109 return false; 110 111 case CustomErrorsModes.On: 112 return true; 113 114 case CustomErrorsModes.RemoteOnly: 115 return(!isLocalRequest); 116 117 default: 118 return true; 119 } 120 } 121 122 [System.Security.SecuritySafeCritical] // auto-generated 123 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterActivatedServiceType(Type type)124 public static void RegisterActivatedServiceType(Type type) 125 { 126 ActivatedServiceTypeEntry entry = new ActivatedServiceTypeEntry(type); 127 RemotingConfiguration.RegisterActivatedServiceType(entry); 128 } // RegisterActivatedServiceType 129 130 131 [System.Security.SecuritySafeCritical] // auto-generated 132 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterActivatedServiceType(ActivatedServiceTypeEntry entry)133 public static void RegisterActivatedServiceType(ActivatedServiceTypeEntry entry) 134 { 135 RemotingConfigHandler.RegisterActivatedServiceType(entry); 136 137 // make sure we're listening for activation requests 138 // (all registrations for activated service types will come through here) 139 if (!s_ListeningForActivationRequests) 140 { 141 s_ListeningForActivationRequests = true; 142 ActivationServices.StartListeningForRemoteRequests(); 143 } 144 } // RegisterActivatedServiceType 145 146 147 [System.Security.SecuritySafeCritical] // auto-generated 148 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterWellKnownServiceType( Type type, String objectUri, WellKnownObjectMode mode)149 public static void RegisterWellKnownServiceType( 150 Type type, String objectUri, WellKnownObjectMode mode) 151 { 152 WellKnownServiceTypeEntry wke = 153 new WellKnownServiceTypeEntry(type, objectUri, mode); 154 RemotingConfiguration.RegisterWellKnownServiceType(wke); 155 } // RegisterWellKnownServiceType 156 157 158 159 [System.Security.SecuritySafeCritical] // auto-generated 160 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterWellKnownServiceType(WellKnownServiceTypeEntry entry)161 public static void RegisterWellKnownServiceType(WellKnownServiceTypeEntry entry) 162 { 163 RemotingConfigHandler.RegisterWellKnownServiceType(entry); 164 } // RegisterWellKnownServiceType 165 166 167 [System.Security.SecuritySafeCritical] // auto-generated 168 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterActivatedClientType(Type type, String appUrl)169 public static void RegisterActivatedClientType(Type type, String appUrl) 170 { 171 ActivatedClientTypeEntry acte = 172 new ActivatedClientTypeEntry(type, appUrl); 173 RemotingConfiguration.RegisterActivatedClientType(acte); 174 } // RegisterActivatedClientType 175 176 177 178 [System.Security.SecuritySafeCritical] // auto-generated 179 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterActivatedClientType(ActivatedClientTypeEntry entry)180 public static void RegisterActivatedClientType(ActivatedClientTypeEntry entry) 181 { 182 RemotingConfigHandler.RegisterActivatedClientType(entry); 183 184 // all registrations for activated client types will come through here 185 RemotingServices.InternalSetRemoteActivationConfigured(); 186 } // RegisterActivatedClientType 187 188 189 190 191 [System.Security.SecuritySafeCritical] // auto-generated 192 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterWellKnownClientType(Type type, String objectUrl)193 public static void RegisterWellKnownClientType(Type type, String objectUrl) 194 { 195 WellKnownClientTypeEntry wke = new WellKnownClientTypeEntry(type, objectUrl); 196 RemotingConfiguration.RegisterWellKnownClientType(wke); 197 } // RegisterWellKnownClientType 198 199 200 201 [System.Security.SecuritySafeCritical] // auto-generated 202 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] RegisterWellKnownClientType(WellKnownClientTypeEntry entry)203 public static void RegisterWellKnownClientType(WellKnownClientTypeEntry entry) 204 { 205 RemotingConfigHandler.RegisterWellKnownClientType(entry); 206 207 // all registrations for wellknown client types will come through here 208 RemotingServices.InternalSetRemoteActivationConfigured(); 209 } // RegisterWellKnownClientType 210 211 212 [System.Security.SecuritySafeCritical] // auto-generated 213 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] GetRegisteredActivatedServiceTypes()214 public static ActivatedServiceTypeEntry[] GetRegisteredActivatedServiceTypes() 215 { 216 return RemotingConfigHandler.GetRegisteredActivatedServiceTypes(); 217 } 218 219 [System.Security.SecuritySafeCritical] // auto-generated 220 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] GetRegisteredWellKnownServiceTypes()221 public static WellKnownServiceTypeEntry[] GetRegisteredWellKnownServiceTypes() 222 { 223 return RemotingConfigHandler.GetRegisteredWellKnownServiceTypes(); 224 } 225 226 227 [System.Security.SecuritySafeCritical] // auto-generated 228 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] GetRegisteredActivatedClientTypes()229 public static ActivatedClientTypeEntry[] GetRegisteredActivatedClientTypes() 230 { 231 return RemotingConfigHandler.GetRegisteredActivatedClientTypes(); 232 } 233 234 [System.Security.SecuritySafeCritical] // auto-generated 235 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] GetRegisteredWellKnownClientTypes()236 public static WellKnownClientTypeEntry[] GetRegisteredWellKnownClientTypes() 237 { 238 return RemotingConfigHandler.GetRegisteredWellKnownClientTypes(); 239 } 240 241 242 // This is used at the client end to check if an activation needs 243 // to go remote. 244 [System.Security.SecuritySafeCritical] // auto-generated 245 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] IsRemotelyActivatedClientType(Type svrType)246 public static ActivatedClientTypeEntry IsRemotelyActivatedClientType(Type svrType) 247 { 248 if (svrType == null) 249 throw new ArgumentNullException("svrType"); 250 251 RuntimeType rt = svrType as RuntimeType; 252 if (rt == null) 253 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); 254 255 return RemotingConfigHandler.IsRemotelyActivatedClientType(rt); 256 } 257 258 // This is used at the client end to check if an activation needs 259 // to go remote. 260 261 [System.Security.SecuritySafeCritical] // auto-generated 262 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] IsRemotelyActivatedClientType(String typeName, String assemblyName)263 public static ActivatedClientTypeEntry IsRemotelyActivatedClientType(String typeName, String assemblyName) 264 { 265 return RemotingConfigHandler.IsRemotelyActivatedClientType(typeName, assemblyName); 266 } 267 268 269 // This is used at the client end to check if a "new Foo" needs to 270 // happen via a Connect() under the covers. 271 [System.Security.SecuritySafeCritical] // auto-generated 272 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] IsWellKnownClientType(Type svrType)273 public static WellKnownClientTypeEntry IsWellKnownClientType(Type svrType) 274 { 275 if (svrType == null) 276 throw new ArgumentNullException("svrType"); 277 278 RuntimeType rt = svrType as RuntimeType; 279 if (rt == null) 280 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); 281 282 return RemotingConfigHandler.IsWellKnownClientType(rt); 283 } 284 285 // This is used at the client end to check if a "new Foo" needs to 286 // happen via a Connect() under the covers. 287 [System.Security.SecuritySafeCritical] // auto-generated 288 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] IsWellKnownClientType(String typeName, String assemblyName)289 public static WellKnownClientTypeEntry IsWellKnownClientType(String typeName, 290 String assemblyName) 291 { 292 return RemotingConfigHandler.IsWellKnownClientType(typeName, assemblyName); 293 } 294 295 // This is used at the server end to check if a type being activated 296 // is explicitly allowed by the server. 297 [System.Security.SecuritySafeCritical] // auto-generated 298 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] IsActivationAllowed(Type svrType)299 public static bool IsActivationAllowed(Type svrType) 300 { 301 RuntimeType rt = svrType as RuntimeType; 302 if (svrType != null && rt == null) 303 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); 304 305 return RemotingConfigHandler.IsActivationAllowed(rt); 306 } 307 308 } // class Configuration 309 310 311 312 // 313 // The following classes are used to register and retrieve remoted type information 314 // 315 316 // Base class for all configuration entries 317 [System.Runtime.InteropServices.ComVisible(true)] 318 public class TypeEntry 319 { 320 String _typeName; 321 String _assemblyName; 322 RemoteAppEntry _cachedRemoteAppEntry = null; 323 TypeEntry()324 protected TypeEntry() 325 { 326 // Forbid creation of this class by outside users... 327 } 328 329 public String TypeName { get { return _typeName; } set {_typeName = value;} } 330 331 public String AssemblyName { get { return _assemblyName; } set {_assemblyName = value;} } 332 CacheRemoteAppEntry(RemoteAppEntry entry)333 internal void CacheRemoteAppEntry(RemoteAppEntry entry) {_cachedRemoteAppEntry = entry;} GetRemoteAppEntry()334 internal RemoteAppEntry GetRemoteAppEntry() { return _cachedRemoteAppEntry;} 335 336 } 337 338 [System.Runtime.InteropServices.ComVisible(true)] 339 public class ActivatedClientTypeEntry : TypeEntry 340 { 341 String _appUrl; // url of application to activate the type in 342 343 // optional data 344 IContextAttribute[] _contextAttributes = null; 345 346 ActivatedClientTypeEntry(String typeName, String assemblyName, String appUrl)347 public ActivatedClientTypeEntry(String typeName, String assemblyName, String appUrl) 348 { 349 if (typeName == null) 350 throw new ArgumentNullException("typeName"); 351 if (assemblyName == null) 352 throw new ArgumentNullException("assemblyName"); 353 if (appUrl == null) 354 throw new ArgumentNullException("appUrl"); 355 Contract.EndContractBlock(); 356 357 TypeName = typeName; 358 AssemblyName = assemblyName; 359 _appUrl = appUrl; 360 } // ActivatedClientTypeEntry 361 ActivatedClientTypeEntry(Type type, String appUrl)362 public ActivatedClientTypeEntry(Type type, String appUrl) 363 { 364 if (type == null) 365 throw new ArgumentNullException("type"); 366 if (appUrl == null) 367 throw new ArgumentNullException("appUrl"); 368 Contract.EndContractBlock(); 369 370 RuntimeType rtType = type as RuntimeType; 371 if (rtType == null) 372 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly")); 373 374 TypeName = type.FullName; 375 AssemblyName = rtType.GetRuntimeAssembly().GetSimpleName(); 376 _appUrl = appUrl; 377 } // ActivatedClientTypeEntry 378 379 public String ApplicationUrl { get { return _appUrl; } } 380 381 public Type ObjectType 382 { 383 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 384 get { 385 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 386 return RuntimeTypeHandle.GetTypeByName(TypeName + ", " + AssemblyName, ref stackMark); 387 } 388 } 389 390 public IContextAttribute[] ContextAttributes 391 { 392 get { return _contextAttributes; } 393 set { _contextAttributes = value; } 394 } 395 396 ToString()397 public override String ToString() 398 { 399 return "type='" + TypeName + ", " + AssemblyName + "'; appUrl=" + _appUrl; 400 } 401 402 } // class ActivatedClientTypeEntry 403 404 405 [System.Runtime.InteropServices.ComVisible(true)] 406 public class ActivatedServiceTypeEntry : TypeEntry 407 { 408 // optional data 409 IContextAttribute[] _contextAttributes = null; 410 411 ActivatedServiceTypeEntry(String typeName, String assemblyName)412 public ActivatedServiceTypeEntry(String typeName, String assemblyName) 413 { 414 if (typeName == null) 415 throw new ArgumentNullException("typeName"); 416 if (assemblyName == null) 417 throw new ArgumentNullException("assemblyName"); 418 Contract.EndContractBlock(); 419 TypeName = typeName; 420 AssemblyName = assemblyName; 421 } 422 ActivatedServiceTypeEntry(Type type)423 public ActivatedServiceTypeEntry(Type type) 424 { 425 if (type == null) 426 throw new ArgumentNullException("type"); 427 Contract.EndContractBlock(); 428 429 RuntimeType rtType = type as RuntimeType; 430 if (rtType == null) 431 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly")); 432 433 TypeName = type.FullName; 434 AssemblyName = rtType.GetRuntimeAssembly().GetSimpleName(); 435 } 436 437 public Type ObjectType 438 { 439 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 440 get { 441 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 442 return RuntimeTypeHandle.GetTypeByName(TypeName + ", " + AssemblyName, ref stackMark); 443 } 444 } 445 446 public IContextAttribute[] ContextAttributes 447 { 448 get { return _contextAttributes; } 449 set { _contextAttributes = value; } 450 } 451 452 ToString()453 public override String ToString() 454 { 455 return "type='" + TypeName + ", " + AssemblyName + "'"; 456 } 457 458 } // class ActivatedServiceTypeEntry 459 460 461 [System.Runtime.InteropServices.ComVisible(true)] 462 public class WellKnownClientTypeEntry : TypeEntry 463 { 464 String _objectUrl; 465 466 // optional data 467 String _appUrl = null; // url of application to associate this object with 468 469 WellKnownClientTypeEntry(String typeName, String assemblyName, String objectUrl)470 public WellKnownClientTypeEntry(String typeName, String assemblyName, String objectUrl) 471 { 472 if (typeName == null) 473 throw new ArgumentNullException("typeName"); 474 if (assemblyName == null) 475 throw new ArgumentNullException("assemblyName"); 476 if (objectUrl == null) 477 throw new ArgumentNullException("objectUrl"); 478 Contract.EndContractBlock(); 479 480 TypeName = typeName; 481 AssemblyName = assemblyName; 482 _objectUrl = objectUrl; 483 } 484 WellKnownClientTypeEntry(Type type, String objectUrl)485 public WellKnownClientTypeEntry(Type type, String objectUrl) 486 { 487 if (type == null) 488 throw new ArgumentNullException("type"); 489 if (objectUrl == null) 490 throw new ArgumentNullException("objectUrl"); 491 Contract.EndContractBlock(); 492 493 RuntimeType rtType = type as RuntimeType; 494 if (rtType == null) 495 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); 496 497 TypeName = type.FullName; 498 AssemblyName = rtType.GetRuntimeAssembly().GetSimpleName(); 499 _objectUrl = objectUrl; 500 } 501 502 public String ObjectUrl { get { return _objectUrl; } } 503 504 public Type ObjectType 505 { 506 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 507 get { 508 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 509 return RuntimeTypeHandle.GetTypeByName(TypeName + ", " + AssemblyName, ref stackMark); 510 } 511 } 512 513 public String ApplicationUrl 514 { 515 get { return _appUrl; } 516 set { _appUrl = value; } 517 } 518 ToString()519 public override String ToString() 520 { 521 String str = "type='" + TypeName + ", " + AssemblyName + "'; url=" + _objectUrl; 522 if (_appUrl != null) 523 str += "; appUrl=" + _appUrl; 524 return str; 525 } 526 527 } // class WellKnownClientTypeEntry 528 529 530 [System.Runtime.InteropServices.ComVisible(true)] 531 public class WellKnownServiceTypeEntry : TypeEntry 532 { 533 String _objectUri; 534 WellKnownObjectMode _mode; 535 536 // optional data 537 IContextAttribute[] _contextAttributes = null; 538 WellKnownServiceTypeEntry(String typeName, String assemblyName, String objectUri, WellKnownObjectMode mode)539 public WellKnownServiceTypeEntry(String typeName, String assemblyName, String objectUri, 540 WellKnownObjectMode mode) 541 { 542 if (typeName == null) 543 throw new ArgumentNullException("typeName"); 544 if (assemblyName == null) 545 throw new ArgumentNullException("assemblyName"); 546 if (objectUri == null) 547 throw new ArgumentNullException("objectUri"); 548 Contract.EndContractBlock(); 549 550 TypeName = typeName; 551 AssemblyName = assemblyName; 552 _objectUri = objectUri; 553 _mode = mode; 554 } 555 WellKnownServiceTypeEntry(Type type, String objectUri, WellKnownObjectMode mode)556 public WellKnownServiceTypeEntry(Type type, String objectUri, WellKnownObjectMode mode) 557 { 558 if (type == null) 559 throw new ArgumentNullException("type"); 560 if (objectUri == null) 561 throw new ArgumentNullException("objectUri"); 562 Contract.EndContractBlock(); 563 564 if (!(type is RuntimeType)) 565 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); 566 567 TypeName = type.FullName; 568 AssemblyName = type.Module.Assembly.FullName; 569 _objectUri = objectUri; 570 _mode = mode; 571 } 572 573 public String ObjectUri { get { return _objectUri; } } 574 575 public WellKnownObjectMode Mode { get { return _mode; } } 576 577 public Type ObjectType 578 { 579 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 580 get { 581 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 582 return RuntimeTypeHandle.GetTypeByName(TypeName + ", " + AssemblyName, ref stackMark); 583 } 584 } 585 586 public IContextAttribute[] ContextAttributes 587 { 588 get { return _contextAttributes; } 589 set { _contextAttributes = value; } 590 } 591 592 ToString()593 public override String ToString() 594 { 595 return "type='" + TypeName + ", " + AssemblyName + "'; objectUri=" + _objectUri + 596 "; mode=" + _mode.ToString(); 597 } 598 599 } // class WellKnownServiceTypeEntry 600 601 internal class RemoteAppEntry 602 { 603 String _remoteAppName; 604 String _remoteAppURI; RemoteAppEntry(String appName, String appURI)605 internal RemoteAppEntry(String appName, String appURI) 606 { 607 Contract.Assert(appURI != null, "Bad remote app URI"); 608 _remoteAppName = appName; 609 _remoteAppURI = appURI; 610 } GetAppURI()611 internal String GetAppURI() { return _remoteAppURI;} 612 } // class RemoteAppEntry 613 614 [System.Runtime.InteropServices.ComVisible(true)] 615 public enum CustomErrorsModes { 616 On, 617 Off, 618 RemoteOnly 619 } 620 621 } // namespace System.Runtime.Remoting 622