Merge pull request #3389 from lambdageek/bug-43099
[mono.git] / mcs / class / referencesource / mscorlib / system / AppDomainSetup.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*=============================================================================
7 **
8 ** Class: AppDomainSetup
9 ** 
10 ** <OWNER>blanders</OWNER>
11 **
12 ** Purpose: Defines the settings that the loader uses to find assemblies in an
13 **          AppDomain
14 **
15 ** Date: Dec 22, 2000
16 **
17 =============================================================================*/
18
19 namespace System {
20     using System;
21 #if FEATURE_CLICKONCE        
22 #if !FEATURE_PAL
23     using System.Deployment.Internal.Isolation;
24     using System.Deployment.Internal.Isolation.Manifest;
25     using System.Runtime.Hosting;    
26 #endif
27 #endif
28     using System.Runtime.CompilerServices;
29     using System.Runtime;
30     using System.Text;
31     using System.Threading;
32     using System.Runtime.InteropServices;
33     using System.Runtime.Serialization;
34     using System.Reflection;
35     using System.Security;
36     using System.Security.Permissions;
37     using System.Security.Policy;
38     using System.Globalization;
39     using Path = System.IO.Path;
40     using System.Runtime.Versioning;
41     using System.Diagnostics.Contracts;
42     using System.Collections;
43     using System.Collections.Generic;
44
45     [Serializable]
46     [ClassInterface(ClassInterfaceType.None)]
47     [System.Runtime.InteropServices.ComVisible(true)]
48     public sealed class AppDomainSetup :
49         IAppDomainSetup
50     {
51         [Serializable]
52         internal enum LoaderInformation
53         {
54             // If you add a new value, add the corresponding property
55             // to AppDomain.GetData() and SetData()'s switch statements.
56             ApplicationBaseValue = LOADER_APPLICATION_BASE,
57             ConfigurationFileValue = LOADER_CONFIGURATION_BASE,
58             DynamicBaseValue = LOADER_DYNAMIC_BASE,
59             DevPathValue = LOADER_DEVPATH,
60             ApplicationNameValue = LOADER_APPLICATION_NAME,
61             PrivateBinPathValue = LOADER_PRIVATE_PATH,
62             PrivateBinPathProbeValue = LOADER_PRIVATE_BIN_PATH_PROBE,
63             ShadowCopyDirectoriesValue = LOADER_SHADOW_COPY_DIRECTORIES,
64             ShadowCopyFilesValue = LOADER_SHADOW_COPY_FILES,
65             CachePathValue = LOADER_CACHE_PATH,
66             LicenseFileValue = LOADER_LICENSE_FILE,
67             DisallowPublisherPolicyValue = LOADER_DISALLOW_PUBLISHER_POLICY,
68             DisallowCodeDownloadValue = LOADER_DISALLOW_CODE_DOWNLOAD,
69             DisallowBindingRedirectsValue = LOADER_DISALLOW_BINDING_REDIRECTS,
70             DisallowAppBaseProbingValue = LOADER_DISALLOW_APPBASE_PROBING,
71             ConfigurationBytesValue = LOADER_CONFIGURATION_BYTES,
72             LoaderMaximum = LOADER_MAXIMUM,
73         }
74
75         // This class has an unmanaged representation so be aware you will need to make edits in vm\object.h if you change the order
76         // of these fields or add new ones.
77
78         private string[] _Entries;
79         private LoaderOptimization _LoaderOptimization;
80 #pragma warning disable 169
81         private String _AppBase; // for compat with v1.1
82 #pragma warning restore 169
83         [OptionalField(VersionAdded = 2)]
84         private AppDomainInitializer  _AppDomainInitializer;
85         [OptionalField(VersionAdded = 2)]
86         private string[] _AppDomainInitializerArguments;
87 #if FEATURE_CLICKONCE
88         [OptionalField(VersionAdded = 2)]
89         private ActivationArguments _ActivationArguments;
90 #endif
91 #if FEATURE_CORECLR
92         // On the CoreCLR, this contains just the name of the permission set that we install in the new appdomain.
93         // Not the ToXml().ToString() of an ApplicationTrust object.
94 #endif
95         [OptionalField(VersionAdded = 2)]
96         private string _ApplicationTrust;
97         [OptionalField(VersionAdded = 2)]
98         private byte[] _ConfigurationBytes;
99 #if FEATURE_COMINTEROP
100         [OptionalField(VersionAdded = 3)]
101         private bool _DisableInterfaceCache = false;
102 #endif // FEATURE_COMINTEROP
103         [OptionalField(VersionAdded = 4)]
104         private string _AppDomainManagerAssembly;
105         [OptionalField(VersionAdded = 4)]
106         private string _AppDomainManagerType;
107
108 #if FEATURE_APTCA
109         [OptionalField(VersionAdded = 4)]
110         private string[] _AptcaVisibleAssemblies;
111 #endif
112
113         // A collection of strings used to indicate which breaking changes shouldn't be applied
114         // to an AppDomain. We only use the keys, the values are ignored.
115         [OptionalField(VersionAdded = 4)]
116         private Dictionary<string, object> _CompatFlags;
117
118         [OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
119         private String _TargetFrameworkName;
120
121 #if !FEATURE_CORECLR
122         [NonSerialized]
123         internal AppDomainSortingSetupInfo _AppDomainSortingSetupInfo;
124 #endif
125
126         [OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
127         private bool _CheckedForTargetFrameworkName;
128
129 #if FEATURE_RANDOMIZED_STRING_HASHING
130         [OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
131         private bool _UseRandomizedStringHashing;
132 #endif
133
134         [SecuritySafeCritical]
135         internal AppDomainSetup(AppDomainSetup copy, bool copyDomainBoundData)
136         {
137             string[] mine = Value;
138             if(copy != null) {
139                 string[] other = copy.Value;
140                 int mineSize = _Entries.Length;
141                 int otherSize = other.Length;
142                 int size = (otherSize < mineSize) ? otherSize : mineSize;
143
144                 for (int i = 0; i < size; i++)
145                     mine[i] = other[i];
146
147                 if (size < mineSize)
148                 {
149                     // This case can happen when the copy is a deserialized version of
150                     // an AppDomainSetup object serialized by Everett.
151                     for (int i = size; i < mineSize; i++)
152                         mine[i] = null;
153                 }
154
155                 _LoaderOptimization = copy._LoaderOptimization;
156
157                 _AppDomainInitializerArguments = copy.AppDomainInitializerArguments;
158 #if FEATURE_CLICKONCE
159                 _ActivationArguments = copy.ActivationArguments;
160 #endif
161                 _ApplicationTrust = copy._ApplicationTrust;
162                 if (copyDomainBoundData)
163                     _AppDomainInitializer = copy.AppDomainInitializer;
164                 else
165                     _AppDomainInitializer = null;
166
167                 _ConfigurationBytes = copy.GetConfigurationBytes();
168 #if FEATURE_COMINTEROP
169                 _DisableInterfaceCache = copy._DisableInterfaceCache;
170 #endif // FEATURE_COMINTEROP
171                 _AppDomainManagerAssembly = copy.AppDomainManagerAssembly;
172                 _AppDomainManagerType = copy.AppDomainManagerType;
173 #if FEATURE_APTCA
174                 _AptcaVisibleAssemblies = copy.PartialTrustVisibleAssemblies;
175 #endif
176
177                 if (copy._CompatFlags != null)
178                 {
179                     SetCompatibilitySwitches(copy._CompatFlags.Keys);
180                 }
181
182 #if !FEATURE_CORECLR
183                 if(copy._AppDomainSortingSetupInfo != null)
184                 {
185                     _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo(copy._AppDomainSortingSetupInfo);
186                 }
187 #endif
188                 _TargetFrameworkName = copy._TargetFrameworkName;
189
190 #if FEATURE_RANDOMIZED_STRING_HASHING
191                 _UseRandomizedStringHashing = copy._UseRandomizedStringHashing;
192 #endif
193
194             }
195             else 
196                 _LoaderOptimization = LoaderOptimization.NotSpecified;
197         }
198
199         public AppDomainSetup()
200         {
201             _LoaderOptimization = LoaderOptimization.NotSpecified;
202         }
203
204 #if FEATURE_CLICKONCE
205         // Creates an AppDomainSetup object from an application identity.
206         [ResourceExposure(ResourceScope.Machine)]
207         [ResourceConsumption(ResourceScope.Machine)]
208         public AppDomainSetup (ActivationContext activationContext) : this (new ActivationArguments(activationContext)) {}
209
210         [System.Security.SecuritySafeCritical]  // auto-generated
211         [ResourceExposure(ResourceScope.Machine)]
212         [ResourceConsumption(ResourceScope.Machine)]
213         public AppDomainSetup (ActivationArguments activationArguments) {
214             if (activationArguments == null)
215                 throw new ArgumentNullException("activationArguments");
216             Contract.EndContractBlock();
217
218             _LoaderOptimization = LoaderOptimization.NotSpecified;
219             ActivationArguments = activationArguments;
220
221             Contract.Assert(activationArguments.ActivationContext != null, "Cannot set base directory without activation context");
222             string entryPointPath = CmsUtils.GetEntryPointFullPath(activationArguments);
223             if (!String.IsNullOrEmpty(entryPointPath))
224                 SetupDefaults(entryPointPath);
225             else
226                 ApplicationBase = activationArguments.ActivationContext.ApplicationDirectory;
227
228         }
229 #endif // !FEATURE_CLICKONCE
230
231         #if FEATURE_CORECLR
232         [System.Security.SecurityCritical] // auto-generated
233         #endif
234         [ResourceExposure(ResourceScope.Machine)]
235         [ResourceConsumption(ResourceScope.Machine)]
236         internal void SetupDefaults(string imageLocation, bool imageLocationAlreadyNormalized = false) {
237             char[] sep = {'\\', '/'};
238             int i = imageLocation.LastIndexOfAny(sep);
239
240             if (i == -1) {
241                 ApplicationName = imageLocation;
242             }
243             else {
244                 ApplicationName = imageLocation.Substring(i+1);
245                 string appBase = imageLocation.Substring(0, i+1);
246
247                 if (imageLocationAlreadyNormalized)
248                     Value[(int) LoaderInformation.ApplicationBaseValue] = appBase;
249                 else 
250                     ApplicationBase = appBase;
251             }
252             ConfigurationFile = ApplicationName + AppDomainSetup.ConfigurationExtension;
253         }
254
255         internal string[] Value
256         {
257             get {
258                 if( _Entries == null)
259                     _Entries = new String[LOADER_MAXIMUM];
260                 return _Entries;
261             }
262         }
263
264         internal String GetUnsecureApplicationBase()
265         {
266             return Value[(int) LoaderInformation.ApplicationBaseValue];
267         }
268
269         public string AppDomainManagerAssembly
270         {
271             get { return _AppDomainManagerAssembly; }
272             set { _AppDomainManagerAssembly = value; }
273         }
274
275         public string AppDomainManagerType
276         {
277             get { return _AppDomainManagerType; }
278             set { _AppDomainManagerType = value; }
279         }
280
281 #if FEATURE_APTCA
282         public string[] PartialTrustVisibleAssemblies
283         {
284             get { return _AptcaVisibleAssemblies; }
285             set { 
286                 if (value != null) {
287                     _AptcaVisibleAssemblies = (string[])value.Clone(); 
288                     Array.Sort<string>(_AptcaVisibleAssemblies, StringComparer.OrdinalIgnoreCase);
289                 }
290                 else {
291                     _AptcaVisibleAssemblies = null;
292                 }
293             }
294         }
295 #endif
296
297         public String ApplicationBase
298         {
299             #if FEATURE_CORECLR
300             [System.Security.SecurityCritical] // auto-generated
301             #else
302             [System.Security.SecuritySafeCritical]
303             #endif
304             [Pure]
305             [ResourceExposure(ResourceScope.Machine)]
306             [ResourceConsumption(ResourceScope.Machine)]
307             get {
308                 return VerifyDir(GetUnsecureApplicationBase(), false);
309             }
310
311             #if FEATURE_CORECLR
312             [System.Security.SecurityCritical] // auto-generated
313             #endif
314             [ResourceExposure(ResourceScope.Machine)]
315             [ResourceConsumption(ResourceScope.Machine)]
316             set {
317                 Value[(int) LoaderInformation.ApplicationBaseValue] = NormalizePath(value, false);
318             }
319         }
320
321         [System.Security.SecuritySafeCritical]
322         private string NormalizePath(string path, bool useAppBase)
323         {
324             if(path == null)
325                 return null;
326
327             // If we add very long file name support ("\\?\") to the Path class then this is unnecesary,
328             // but we do not plan on doing this for now.
329
330             // Long path checks can be quirked, and as loading default quirks too early in the setup of an AppDomain is risky
331             // we'll avoid checking path lengths- we'll still fail at MAX_PATH later if we're !useAppBase when we call Path's
332             // NormalizePath.
333             if (!useAppBase)
334                 path = System.Security.Util.URLString.PreProcessForExtendedPathRemoval(
335                     checkPathLength: false,
336                     url: path,
337                     isFileUrl: false);
338
339             int len = path.Length;
340             if (len == 0)
341                 return null;
342
343             bool UNCpath = false;
344
345             if ((len > 7) &&
346                 (String.Compare( path, 0, "file:", 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) {
347                 int trim;
348                 
349                 if (path[6] == '\\') {
350                     if ((path[7] == '\\') || (path[7] == '/')) {
351
352                         // Don't allow "file:\\\\", because we can't tell the difference
353                         // with it for "file:\\" + "\\server" and "file:\\\" + "\localpath"
354                         if ( (len > 8) && 
355                              ((path[8] == '\\') || (path[8] == '/')) )
356                             throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
357                         
358                         // file:\\\ means local path
359                         else
360                             trim = 8;
361                     }
362
363                     // file:\\ means remote server
364                     else {
365                         trim = 5;
366                         UNCpath = true;
367                     }
368                 }
369
370                 // local path
371                 else if (path[7] == '/')
372                     trim = 8;
373
374                 // remote
375                 else {
376                     // file://\\remote
377                     if ( (len > 8) && (path[7] == '\\') && (path[8] == '\\') )
378                         trim = 7;
379                     else { // file://remote
380                         trim = 5;
381                         // Create valid UNC path by changing
382                         // all occurences of '/' to '\\' in path
383                         System.Text.StringBuilder winPathBuilder =
384                             new System.Text.StringBuilder(len);
385                         for (int i = 0; i < len; i++) {
386                             char c = path[i];
387                             if (c == '/')
388                                 winPathBuilder.Append('\\');
389                             else
390                                 winPathBuilder.Append(c);
391                         }
392                         path = winPathBuilder.ToString();
393                     }
394                     UNCpath = true;
395                 }
396
397                 path = path.Substring(trim);
398                 len -= trim;
399             }
400
401             bool localPath;
402
403             // UNC
404             if (UNCpath ||
405                 ( (len > 1) &&
406                   ( (path[0] == '/') || (path[0] == '\\') ) &&
407                   ( (path[1] == '/') || (path[1] == '\\') ) ))
408                 localPath = false;
409
410             else {
411                 int colon = path.IndexOf(':') + 1;
412
413                 // protocol other than file:
414                 if ((colon != 0) &&
415                     (len > colon+1) &&
416                     ( (path[colon] == '/') || (path[colon] == '\\') ) &&
417                     ( (path[colon+1] == '/') || (path[colon+1] == '\\') ))
418                     localPath = false;
419
420                 else
421                     localPath = true;
422             }
423
424             if (localPath) 
425             {
426                 if (useAppBase &&
427                     ((len == 1) || (path[1] != ':'))) 
428                 {
429                     String appBase = Value[(int)LoaderInformation.ApplicationBaseValue];
430
431                     if ((appBase == null) || (appBase.Length == 0))
432                         throw new MemberAccessException(Environment.GetResourceString("AppDomain_AppBaseNotSet"));
433
434                     StringBuilder result = StringBuilderCache.Acquire();
435
436                     bool slash = false;
437                     if ((path[0] == '/') || (path[0] == '\\')) {
438                         // Emulate Path.GetPathRoot without hitting code paths that check quirks
439                         string pathRoot = AppDomain.NormalizePath(appBase, fullCheck: false);
440                         pathRoot = pathRoot.Substring(0, System.IO.PathInternal.GetRootLength(pathRoot));
441                         if (pathRoot.Length == 0) { // URL
442                             int index = appBase.IndexOf(":/", StringComparison.Ordinal);
443                             if (index == -1)
444                                 index = appBase.IndexOf(":\\", StringComparison.Ordinal);
445
446                             // Get past last slashes of "url:http://"
447                             int urlLen = appBase.Length;
448                             for (index += 1;
449                                  (index < urlLen) && ((appBase[index] == '/') || (appBase[index] == '\\'));
450                                  index++) ;
451
452                             // Now find the next slash to get domain name
453                             for (; (index < urlLen) && (appBase[index] != '/') && (appBase[index] != '\\');
454                                 index++) ;
455
456                             pathRoot = appBase.Substring(0, index);
457                         }
458
459                         result.Append(pathRoot);
460                         slash = true;
461                     }
462                     else
463                         result.Append(appBase);
464
465                     // Make sure there's a slash separator (and only one)
466                     int aLen = result.Length - 1;
467                     if ((result[aLen] != '/') &&
468                         (result[aLen] != '\\')) {
469                         if (!slash) {
470                             if (appBase.IndexOf(":/", StringComparison.Ordinal) == -1)
471                                 result.Append('\\');
472                             else
473                                 result.Append('/');
474                         }
475                     }
476                     else if (slash)
477                         result.Remove(aLen, 1);
478
479                     result.Append(path);
480                     path = StringBuilderCache.GetStringAndRelease(result);
481                 }
482                 else
483                 {
484                     path = AppDomain.NormalizePath(path, fullCheck: true);
485                 }
486             }
487
488             return path;
489         }
490
491         private bool IsFilePath(String path)
492         {
493             return (path[1] == ':') || ( (path[0] == '\\') && (path[1] == '\\') );
494         }
495
496         internal static String ApplicationBaseKey
497         {
498             get {
499                 return ACTAG_APP_BASE_URL;
500             }
501         }
502
503         public String ConfigurationFile
504         {
505             [System.Security.SecuritySafeCritical]  // auto-generated
506             [ResourceExposure(ResourceScope.Machine)]
507             [ResourceConsumption(ResourceScope.Machine)]
508             get {
509                 return VerifyDir(Value[(int) LoaderInformation.ConfigurationFileValue], true);
510             }
511
512             [ResourceExposure(ResourceScope.Machine)]
513             [ResourceConsumption(ResourceScope.Machine)]
514             set {
515                 Value[(int) LoaderInformation.ConfigurationFileValue] = value;
516             }
517         }
518
519         // Used by the ResourceManager internally.  This must not do any 
520         // security checks to avoid infinite loops.
521         internal String ConfigurationFileInternal
522         {
523             [ResourceExposure(ResourceScope.Machine)]
524             [ResourceConsumption(ResourceScope.Machine)]
525             get {
526                 return NormalizePath(Value[(int) LoaderInformation.ConfigurationFileValue], true);
527             }
528         }
529
530         internal static String ConfigurationFileKey
531         {
532             get {
533                 return ACTAG_APP_CONFIG_FILE;
534             }
535         }
536
537         public byte[] GetConfigurationBytes()
538         {
539             if (_ConfigurationBytes == null)
540                 return null;
541
542             return (byte[]) _ConfigurationBytes.Clone();
543         }
544
545         public void SetConfigurationBytes(byte[] value)
546         {
547             _ConfigurationBytes = value;
548         }
549
550         private static String ConfigurationBytesKey
551         {
552             get {
553                 return ACTAG_APP_CONFIG_BLOB;
554             }
555         }
556
557         // only needed by AppDomain.Setup(). Not really needed by users. 
558         internal Dictionary<string, object> GetCompatibilityFlags()
559         {
560             return _CompatFlags;
561         }
562
563         public void SetCompatibilitySwitches(IEnumerable<String> switches)
564         {
565
566 #if !FEATURE_CORECLR
567             if(_AppDomainSortingSetupInfo != null)
568             {
569                 _AppDomainSortingSetupInfo._useV2LegacySorting = false;
570                 _AppDomainSortingSetupInfo._useV4LegacySorting = false;
571             }
572 #endif
573
574 #if FEATURE_RANDOMIZED_STRING_HASHING
575             _UseRandomizedStringHashing = false;
576 #endif
577             if (switches != null)
578             {
579                 _CompatFlags = new Dictionary<string, object>();
580                 foreach (String str in switches) 
581                 {
582 #if !FEATURE_CORECLR
583                     if(StringComparer.OrdinalIgnoreCase.Equals("NetFx40_Legacy20SortingBehavior", str)) {
584                         if(_AppDomainSortingSetupInfo == null)
585                         {
586                             _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
587                         }
588                         _AppDomainSortingSetupInfo._useV2LegacySorting = true;
589                     }
590
591                     if(StringComparer.OrdinalIgnoreCase.Equals("NetFx45_Legacy40SortingBehavior", str)) {
592                         if(_AppDomainSortingSetupInfo == null)
593                         {
594                             _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
595                         }
596                         _AppDomainSortingSetupInfo._useV4LegacySorting = true;
597                     }
598 #endif
599
600 #if FEATURE_RANDOMIZED_STRING_HASHING
601                     if(StringComparer.OrdinalIgnoreCase.Equals("UseRandomizedStringHashAlgorithm", str)) {
602                         _UseRandomizedStringHashing = true;
603                     }
604 #endif
605
606                     _CompatFlags.Add(str, null);
607                 }
608             }
609             else
610             {
611                 _CompatFlags = null;
612             }
613
614         }
615
616         // A target Framework moniker, in a format parsible by the FrameworkName class.
617         public String TargetFrameworkName {
618             get {
619                 return _TargetFrameworkName;
620             }
621             set {
622                 _TargetFrameworkName = value;
623             }
624         }
625
626         internal bool CheckedForTargetFrameworkName
627         {
628             get { return _CheckedForTargetFrameworkName; }
629             set { _CheckedForTargetFrameworkName = value; }
630         }
631
632 #if !FEATURE_CORECLR
633         [SecurityCritical]
634         public void SetNativeFunction(string functionName, int functionVersion, IntPtr functionPointer) 
635         {
636             if(functionName == null) 
637             {
638                 throw new ArgumentNullException("functionName");
639             }
640
641             if(functionPointer == IntPtr.Zero)
642             {
643                 throw new ArgumentNullException("functionPointer");
644             }
645
646             if(String.IsNullOrWhiteSpace(functionName))
647             {
648                 throw new ArgumentException(Environment.GetResourceString("Argument_NPMSInvalidName"), "functionName");
649             }
650
651             Contract.EndContractBlock();
652
653             if(functionVersion < 1)
654             {
655                 throw new ArgumentException(Environment.GetResourceString("ArgumentException_MinSortingVersion", 1, functionName));
656             }
657
658             if(_AppDomainSortingSetupInfo == null)
659             {
660                 _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
661             }
662
663             if(String.Equals(functionName, "IsNLSDefinedString", StringComparison.OrdinalIgnoreCase))
664             {
665                 _AppDomainSortingSetupInfo._pfnIsNLSDefinedString = functionPointer;
666             }
667
668             if (String.Equals(functionName, "CompareStringEx", StringComparison.OrdinalIgnoreCase))
669             {
670                 _AppDomainSortingSetupInfo._pfnCompareStringEx = functionPointer;
671             }
672
673             if (String.Equals(functionName, "LCMapStringEx", StringComparison.OrdinalIgnoreCase))
674             {
675                 _AppDomainSortingSetupInfo._pfnLCMapStringEx = functionPointer;
676             }
677
678             if (String.Equals(functionName, "FindNLSStringEx", StringComparison.OrdinalIgnoreCase))
679             {
680                 _AppDomainSortingSetupInfo._pfnFindNLSStringEx = functionPointer;
681             }
682
683             if (String.Equals(functionName, "CompareStringOrdinal", StringComparison.OrdinalIgnoreCase))
684             {
685                 _AppDomainSortingSetupInfo._pfnCompareStringOrdinal = functionPointer;
686             }
687
688             if (String.Equals(functionName, "GetNLSVersionEx", StringComparison.OrdinalIgnoreCase))
689             {
690                 _AppDomainSortingSetupInfo._pfnGetNLSVersionEx = functionPointer;
691             }
692
693             if (String.Equals(functionName, "FindStringOrdinal", StringComparison.OrdinalIgnoreCase))
694             {
695                 _AppDomainSortingSetupInfo._pfnFindStringOrdinal = functionPointer;
696             }
697         }
698 #endif
699
700         public String DynamicBase
701         {
702             [System.Security.SecuritySafeCritical]  // auto-generated
703             [ResourceExposure(ResourceScope.Machine)]
704             [ResourceConsumption(ResourceScope.Machine)]
705             get {
706                 return VerifyDir(Value[(int) LoaderInformation.DynamicBaseValue], true);
707             }
708
709             [System.Security.SecuritySafeCritical]  // auto-generated
710             [ResourceExposure(ResourceScope.Machine)]
711             [ResourceConsumption(ResourceScope.Machine)]
712             set {
713                 if (value == null)
714                     Value[(int) LoaderInformation.DynamicBaseValue] = null;
715                 else {
716                     if(ApplicationName == null)
717                         throw new MemberAccessException(Environment.GetResourceString("AppDomain_RequireApplicationName"));
718                     
719                     StringBuilder s = new StringBuilder( NormalizePath(value, false) );
720                     s.Append('\\');
721                     string h = ParseNumbers.IntToString(ApplicationName.GetLegacyNonRandomizedHashCode(),
722                                                         16, 8, '0', ParseNumbers.PrintAsI4);
723                     s.Append(h);
724                     
725                     Value[(int) LoaderInformation.DynamicBaseValue] = s.ToString();
726                 }
727             }
728         }
729
730         internal static String DynamicBaseKey
731         {
732             get {
733                 return ACTAG_APP_DYNAMIC_BASE;
734             }
735         }
736
737
738         public bool DisallowPublisherPolicy
739         {
740             get 
741             {
742                 return (Value[(int) LoaderInformation.DisallowPublisherPolicyValue] != null);
743             }
744             set
745             {
746                 if (value)
747                     Value[(int) LoaderInformation.DisallowPublisherPolicyValue]="true";
748                 else
749                     Value[(int) LoaderInformation.DisallowPublisherPolicyValue]=null;
750             }
751         }
752
753
754         public bool DisallowBindingRedirects
755         {
756             get 
757             {
758                 return (Value[(int) LoaderInformation.DisallowBindingRedirectsValue] != null);
759             }
760             set
761             {
762                 if (value)
763                     Value[(int) LoaderInformation.DisallowBindingRedirectsValue] = "true";
764                 else
765                     Value[(int) LoaderInformation.DisallowBindingRedirectsValue] = null;
766             }
767         }
768
769         public bool DisallowCodeDownload
770         {
771             get 
772             {
773                 return (Value[(int) LoaderInformation.DisallowCodeDownloadValue] != null);
774             }
775             set
776             {
777                 if (value)
778                     Value[(int) LoaderInformation.DisallowCodeDownloadValue] = "true";
779                 else
780                     Value[(int) LoaderInformation.DisallowCodeDownloadValue] = null;
781             }
782         }
783
784
785         public bool DisallowApplicationBaseProbing
786         {
787             get 
788             {
789                 return (Value[(int) LoaderInformation.DisallowAppBaseProbingValue] != null);
790             }
791             set
792             {
793                 if (value)
794                     Value[(int) LoaderInformation.DisallowAppBaseProbingValue] = "true";
795                 else
796                     Value[(int) LoaderInformation.DisallowAppBaseProbingValue] = null;
797             }
798         }
799
800         [System.Security.SecurityCritical]  // auto-generated
801         [ResourceExposure(ResourceScope.Machine)]
802         [ResourceConsumption(ResourceScope.Machine)]
803         private String VerifyDir(String dir, bool normalize)
804         {
805             if (dir != null)
806             {
807                 if (dir.Length == 0)
808                 {
809                     dir = null;
810                 }
811                 else
812                 {
813                     if (normalize)
814                         dir = NormalizePath(dir, true);
815
816                     // The only way AppDomainSetup is exposed in coreclr is through the AppDomainManager 
817                     // and the AppDomainManager is a SecurityCritical type. Also, all callers of callstacks 
818                     // leading from VerifyDir are SecurityCritical. So we can remove the Demand because 
819                     // we have validated that all callers are SecurityCritical
820 #if !FEATURE_CORECLR
821                     if (IsFilePath(dir))
822                     {
823                         // If we've already normalized we don't need to do it again, and can avoid hitting
824                         // quirks in FileIOPermission.
825                         new FileIOPermission(
826                             access: FileIOPermissionAccess.PathDiscovery,
827                             pathList: new string[] { dir },
828                             checkForDuplicates: false,
829                             needFullPath: false).Demand();
830                     }
831 #endif // !FEATURE_CORECLR
832                 }
833             }
834
835             return dir;
836         }
837
838         [System.Security.SecurityCritical]  // auto-generated
839         [ResourceExposure(ResourceScope.Machine)]
840         [ResourceConsumption(ResourceScope.Machine)]
841         private void VerifyDirList(String dirs)
842         {
843             if (dirs != null) {
844                 String[] dirArray = dirs.Split(';');
845                 int len = dirArray.Length;
846                 
847                 for (int i = 0; i < len; i++)
848                     VerifyDir(dirArray[i], true);
849             }
850         }
851
852         internal String DeveloperPath
853         {
854             [System.Security.SecurityCritical]  // auto-generated
855             [ResourceExposure(ResourceScope.Machine)]
856             [ResourceConsumption(ResourceScope.Machine)]
857             get {
858                 String dirs = Value[(int) LoaderInformation.DevPathValue];
859                 VerifyDirList(dirs);
860                 return dirs;
861             }
862
863             [ResourceExposure(ResourceScope.Machine)]
864             [ResourceConsumption(ResourceScope.Machine)]
865             set {
866                 if(value == null)
867                     Value[(int) LoaderInformation.DevPathValue] = null;
868                 else {
869                     String[] directories = value.Split(';');
870                     int size = directories.Length;
871                     StringBuilder newPath = StringBuilderCache.Acquire();
872                     bool fDelimiter = false;
873                         
874                     for(int i = 0; i < size; i++) {
875                         if(directories[i].Length != 0) {
876                             if(fDelimiter) 
877                                 newPath.Append(";");
878                             else
879                                 fDelimiter = true;
880                             
881                             newPath.Append(Path.GetFullPathInternal(directories[i]));
882                         }
883                     }
884                     
885                     String newString = StringBuilderCache.GetStringAndRelease(newPath);
886                     if (newString.Length == 0)
887                         Value[(int) LoaderInformation.DevPathValue] = null;
888                     else
889                         Value[(int) LoaderInformation.DevPathValue] = newString;
890                 }
891             }
892         }
893         
894         internal static String DisallowPublisherPolicyKey
895         {
896             get
897             {
898                 return ACTAG_DISALLOW_APPLYPUBLISHERPOLICY;
899             }
900         }
901
902         internal static String DisallowCodeDownloadKey
903         {
904             get
905             {
906                 return ACTAG_CODE_DOWNLOAD_DISABLED;
907             }
908         }
909
910         internal static String DisallowBindingRedirectsKey
911         {
912             get
913             {
914                 return ACTAG_DISALLOW_APP_BINDING_REDIRECTS;
915             }
916         }
917
918         internal static String DeveloperPathKey
919         {
920             get {
921                 return ACTAG_DEV_PATH;
922             }
923         }
924
925         internal static String DisallowAppBaseProbingKey
926         {
927             get
928             {
929                 return ACTAG_DISALLOW_APP_BASE_PROBING;
930             }
931         }
932
933         public String ApplicationName
934         {
935             get {
936                 return Value[(int) LoaderInformation.ApplicationNameValue];
937             }
938
939             set {
940                 Value[(int) LoaderInformation.ApplicationNameValue] = value;
941             }
942         }
943
944         internal static String ApplicationNameKey
945         {
946             get {
947                 return ACTAG_APP_NAME;
948             }
949         }
950
951         [XmlIgnoreMember]
952         public AppDomainInitializer AppDomainInitializer
953         {
954             get {
955                 return _AppDomainInitializer;
956             }
957
958             set {
959                 _AppDomainInitializer = value;
960             }
961         }
962         public string[] AppDomainInitializerArguments
963         {
964             get {
965                 return _AppDomainInitializerArguments;
966             }
967
968             set {
969                 _AppDomainInitializerArguments = value;
970             }
971         }
972
973 #if FEATURE_CLICKONCE
974         [XmlIgnoreMember]
975         public ActivationArguments ActivationArguments {
976             [Pure]
977             get {
978                 return _ActivationArguments;
979             }
980             set {
981                 _ActivationArguments = value;
982             }
983         }
984 #endif // !FEATURE_CLICKONCE
985
986         internal ApplicationTrust InternalGetApplicationTrust()
987         {
988             
989             if (_ApplicationTrust == null) return null;
990
991
992 #if FEATURE_CORECLR            
993             ApplicationTrust grantSet = new ApplicationTrust(NamedPermissionSet.GetBuiltInSet(_ApplicationTrust));
994 #else
995             SecurityElement securityElement = SecurityElement.FromString(_ApplicationTrust);
996             ApplicationTrust grantSet = new ApplicationTrust();
997             grantSet.FromXml(securityElement);
998 #endif
999             return grantSet;
1000         }
1001
1002 #if FEATURE_CORECLR
1003         internal void InternalSetApplicationTrust(String permissionSetName)
1004         {
1005             _ApplicationTrust = permissionSetName;
1006         }
1007 #else
1008         internal void InternalSetApplicationTrust(ApplicationTrust value)
1009         {
1010             if (value != null)
1011             {
1012                 _ApplicationTrust = value.ToXml().ToString();
1013             }
1014             else
1015             {
1016                 _ApplicationTrust = null;
1017             }
1018         }
1019 #endif
1020
1021 #if FEATURE_CLICKONCE
1022         [XmlIgnoreMember]
1023         public ApplicationTrust ApplicationTrust 
1024         {
1025             get {
1026                 return InternalGetApplicationTrust();
1027             }
1028             set {
1029                 InternalSetApplicationTrust(value);
1030             }
1031         }
1032 #else // FEATURE_CLICKONCE
1033         [XmlIgnoreMember]
1034         internal ApplicationTrust ApplicationTrust
1035         {
1036             get {
1037                 return InternalGetApplicationTrust();
1038             }
1039 #if !FEATURE_CORECLR            
1040             set {
1041                 InternalSetApplicationTrust(value);
1042             }
1043 #endif 
1044         }
1045 #endif // FEATURE_CLICKONCE
1046
1047         public String PrivateBinPath
1048         {
1049             [System.Security.SecuritySafeCritical]  // auto-generated
1050             [ResourceExposure(ResourceScope.Machine)]
1051             [ResourceConsumption(ResourceScope.Machine)]
1052             get {
1053                 String dirs = Value[(int) LoaderInformation.PrivateBinPathValue];
1054                 VerifyDirList(dirs);
1055                 return dirs;
1056             }
1057
1058             [ResourceExposure(ResourceScope.Machine)]
1059             [ResourceConsumption(ResourceScope.Machine)]
1060             set {
1061                 Value[(int) LoaderInformation.PrivateBinPathValue] = value;
1062             }
1063         }
1064
1065         internal static String PrivateBinPathKey
1066         {
1067             get {
1068                 return ACTAG_APP_PRIVATE_BINPATH;
1069             }
1070         }
1071
1072
1073         public String PrivateBinPathProbe
1074         {
1075             get {
1076                 return Value[(int) LoaderInformation.PrivateBinPathProbeValue];
1077             }
1078
1079             set {
1080                 Value[(int) LoaderInformation.PrivateBinPathProbeValue] = value;
1081             }
1082         }
1083
1084         internal static String PrivateBinPathProbeKey
1085         {
1086             get {
1087                 return ACTAG_BINPATH_PROBE_ONLY;
1088             }
1089         }
1090
1091         public String ShadowCopyDirectories
1092         {
1093             [System.Security.SecuritySafeCritical]  // auto-generated
1094             [ResourceExposure(ResourceScope.Machine)]
1095             [ResourceConsumption(ResourceScope.Machine)]
1096             get {
1097                 String dirs = Value[(int) LoaderInformation.ShadowCopyDirectoriesValue];
1098                 VerifyDirList(dirs);
1099                 return dirs;
1100             }
1101
1102             [ResourceExposure(ResourceScope.Machine)]
1103             [ResourceConsumption(ResourceScope.Machine)]
1104             set {
1105                 Value[(int) LoaderInformation.ShadowCopyDirectoriesValue] = value;
1106             }
1107         }
1108
1109         internal static String ShadowCopyDirectoriesKey
1110         {
1111             get {
1112                 return ACTAG_APP_SHADOW_COPY_DIRS;
1113             }
1114         }
1115
1116         public String ShadowCopyFiles
1117         {
1118             get {
1119                 return Value[(int) LoaderInformation.ShadowCopyFilesValue];
1120             }
1121
1122             set {
1123                 if((value != null) && 
1124                    (String.Compare(value, "true", StringComparison.OrdinalIgnoreCase) == 0))
1125                     Value[(int) LoaderInformation.ShadowCopyFilesValue] = value;
1126                 else
1127                     Value[(int) LoaderInformation.ShadowCopyFilesValue] = null;
1128             }
1129         }
1130
1131         internal static String ShadowCopyFilesKey
1132         {
1133             get {
1134                 return ACTAG_FORCE_CACHE_INSTALL;
1135             }
1136         }
1137
1138         public String CachePath
1139         {
1140             [System.Security.SecuritySafeCritical]  // auto-generated
1141             [ResourceExposure(ResourceScope.Machine)]
1142             [ResourceConsumption(ResourceScope.Machine)]
1143             get {
1144                 return VerifyDir(Value[(int) LoaderInformation.CachePathValue], false);
1145             }
1146
1147             [ResourceExposure(ResourceScope.Machine)]
1148             [ResourceConsumption(ResourceScope.Machine)]
1149             set {
1150                 Value[(int) LoaderInformation.CachePathValue] = NormalizePath(value, false);
1151             }
1152         }
1153
1154         internal static String CachePathKey
1155         {
1156             get {
1157                 return ACTAG_APP_CACHE_BASE;
1158             }
1159         }
1160
1161         public String LicenseFile
1162         {
1163             [System.Security.SecuritySafeCritical]  // auto-generated
1164             [ResourceExposure(ResourceScope.Machine)]
1165             [ResourceConsumption(ResourceScope.Machine)]
1166             get {
1167                 return VerifyDir(Value[(int) LoaderInformation.LicenseFileValue], true);
1168             }
1169
1170             [ResourceExposure(ResourceScope.Machine)]
1171             [ResourceConsumption(ResourceScope.Machine)]
1172             set {
1173                 Value[(int) LoaderInformation.LicenseFileValue] = value;
1174             }
1175         }
1176
1177         public LoaderOptimization LoaderOptimization
1178         {
1179             get {
1180                 return _LoaderOptimization;
1181             }
1182
1183             set {
1184                 _LoaderOptimization = value;
1185             }
1186         }
1187
1188         internal static string LoaderOptimizationKey
1189         {
1190             get {
1191                 return LOADER_OPTIMIZATION;
1192             }
1193         }
1194
1195         internal static string ConfigurationExtension
1196         {
1197             get {
1198                 return CONFIGURATION_EXTENSION;
1199             }
1200         }
1201
1202         internal static String PrivateBinPathEnvironmentVariable
1203         {
1204             get {
1205                 return APPENV_RELATIVEPATH;
1206             }
1207         }
1208
1209         internal static string RuntimeConfigurationFile
1210         {
1211             get {
1212                 return MACHINE_CONFIGURATION_FILE;
1213             }
1214         }
1215
1216         internal static string MachineConfigKey
1217         {
1218             get {
1219                 return ACTAG_MACHINE_CONFIG;
1220             }
1221         }
1222
1223         internal static string HostBindingKey
1224         {
1225             get {
1226                 return ACTAG_HOST_CONFIG_FILE;
1227             }
1228         }
1229
1230 #if FEATURE_FUSION
1231         [SecurityCritical]
1232         [ResourceExposure(ResourceScope.None)]
1233         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1234         internal bool UpdateContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, String UpdatedField, IntPtr fusionContext, AppDomainSetup oldADS)
1235         {
1236             String FieldString = Value[(int) FieldValue],
1237                    OldFieldString = (oldADS == null ? null : oldADS.Value[(int) FieldValue]);
1238             if (FieldString != OldFieldString) { // Compare references since strings are immutable
1239                 UpdateContextProperty(fusionContext, FieldKey, UpdatedField == null ? FieldString : UpdatedField);
1240                 return true;
1241             }
1242
1243              return false;
1244         }
1245
1246         [SecurityCritical]
1247         [ResourceExposure(ResourceScope.None)]
1248         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1249         internal void UpdateBooleanContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, IntPtr fusionContext, AppDomainSetup oldADS)
1250         {
1251             if (Value[(int) FieldValue] != null)
1252                 UpdateContextProperty(fusionContext, FieldKey, "true");
1253             else if (oldADS != null && oldADS.Value[(int) FieldValue] != null)
1254                 UpdateContextProperty(fusionContext, FieldKey, "false");
1255         }
1256
1257         [SecurityCritical]
1258         [ResourceExposure(ResourceScope.None)]
1259         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1260         internal static bool ByteArraysAreDifferent(Byte[] A, Byte[] B)
1261         {
1262                 int length = A.Length;
1263                 if (length != B.Length)
1264                     return true;
1265
1266                 for(int i = 0; i < length; i++) {
1267                     if (A[i] != B[i])
1268                         return true;                            
1269                }
1270
1271                 return false;
1272         }
1273
1274         [System.Security.SecurityCritical]  // auto-generated
1275         [ResourceExposure(ResourceScope.None)]
1276         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1277         internal static void UpdateByteArrayContextPropertyIfNeeded(Byte[] NewArray, Byte[] OldArray, String FieldKey, IntPtr fusionContext)
1278         {
1279             if ((NewArray != null && OldArray == null) ||
1280                    (NewArray == null && OldArray != null) ||
1281                    (NewArray != null && OldArray != null && ByteArraysAreDifferent(NewArray, OldArray)))
1282                 UpdateContextProperty(fusionContext, FieldKey, NewArray);
1283         }
1284                 
1285         [System.Security.SecurityCritical]  // auto-generated
1286         [ResourceExposure(ResourceScope.None)]
1287         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
1288         internal void SetupFusionContext(IntPtr fusionContext, AppDomainSetup oldADS)
1289         {
1290             UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationBaseValue, ApplicationBaseKey, null, fusionContext, oldADS);
1291             UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathValue, PrivateBinPathKey, null, fusionContext, oldADS);
1292             UpdateContextPropertyIfNeeded(LoaderInformation.DevPathValue, DeveloperPathKey, null, fusionContext, oldADS);
1293
1294             UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowPublisherPolicyValue, DisallowPublisherPolicyKey, fusionContext, oldADS);
1295             UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowCodeDownloadValue, DisallowCodeDownloadKey, fusionContext, oldADS);
1296             UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowBindingRedirectsValue, DisallowBindingRedirectsKey, fusionContext, oldADS);
1297             UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowAppBaseProbingValue, DisallowAppBaseProbingKey, fusionContext, oldADS);
1298
1299             if(UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyFilesValue, ShadowCopyFilesKey, ShadowCopyFiles, fusionContext, oldADS)) {
1300
1301                 // If we are asking for shadow copy directories then default to
1302                 // only to the ones that are in the private bin path.
1303                 if(Value[(int) LoaderInformation.ShadowCopyDirectoriesValue] == null)
1304                     ShadowCopyDirectories = BuildShadowCopyDirectories();
1305
1306                 UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyDirectoriesValue, ShadowCopyDirectoriesKey, null, fusionContext, oldADS);
1307             }
1308
1309             UpdateContextPropertyIfNeeded(LoaderInformation.CachePathValue, CachePathKey, null, fusionContext, oldADS);
1310             UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathProbeValue, PrivateBinPathProbeKey, PrivateBinPathProbe, fusionContext, oldADS);
1311             UpdateContextPropertyIfNeeded(LoaderInformation.ConfigurationFileValue, ConfigurationFileKey, null, fusionContext, oldADS);
1312
1313             UpdateByteArrayContextPropertyIfNeeded(_ConfigurationBytes, oldADS == null ? null : oldADS.GetConfigurationBytes(), ConfigurationBytesKey, fusionContext);
1314
1315             UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationNameValue, ApplicationNameKey, ApplicationName, fusionContext, oldADS);
1316             UpdateContextPropertyIfNeeded(LoaderInformation.DynamicBaseValue, DynamicBaseKey, null, fusionContext, oldADS);
1317
1318             // Always add the runtime configuration file to the appdomain
1319             UpdateContextProperty(fusionContext, MachineConfigKey, RuntimeEnvironment.GetRuntimeDirectoryImpl() + RuntimeConfigurationFile);
1320
1321             String hostBindingFile = RuntimeEnvironment.GetHostBindingFile();
1322             if(hostBindingFile != null || oldADS != null) // If oldADS != null, we don't know the old value of the hostBindingFile, so we force an update even when hostBindingFile == null.
1323                 UpdateContextProperty(fusionContext, HostBindingKey, hostBindingFile);
1324         }
1325
1326         [System.Security.SecurityCritical]  // auto-generated
1327         [ResourceExposure(ResourceScope.None)]
1328         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1329         internal static extern void UpdateContextProperty(IntPtr fusionContext, string key, Object value);
1330 #endif // FEATURE_FUSION
1331
1332         static internal int Locate(String s)
1333         {
1334             if(String.IsNullOrEmpty(s))
1335                 return -1;
1336 #if FEATURE_FUSION
1337
1338             // verify assumptions hardcoded into the switch below
1339             Contract.Assert('A' == ACTAG_APP_CONFIG_FILE[0]     , "Assumption violated");
1340             Contract.Assert('A' == ACTAG_APP_NAME[0]            , "Assumption violated");
1341             Contract.Assert('A' == ACTAG_APP_BASE_URL[0]        , "Assumption violated");
1342             Contract.Assert('B' == ACTAG_BINPATH_PROBE_ONLY[0]  , "Assumption violated");
1343             Contract.Assert('C' == ACTAG_APP_CACHE_BASE[0]      , "Assumption violated");
1344             Contract.Assert('D' == ACTAG_DEV_PATH[0]            , "Assumption violated");
1345             Contract.Assert('D' == ACTAG_APP_DYNAMIC_BASE[0]    , "Assumption violated");
1346             Contract.Assert('F' == ACTAG_FORCE_CACHE_INSTALL[0] , "Assumption violated");
1347             Contract.Assert('L' == LICENSE_FILE[0]              , "Assumption violated");
1348             Contract.Assert('P' == ACTAG_APP_PRIVATE_BINPATH[0] , "Assumption violated");
1349             Contract.Assert('S' == ACTAG_APP_SHADOW_COPY_DIRS[0], "Assumption violated");
1350             Contract.Assert('D' == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY[0], "Assumption violated");
1351             Contract.Assert('C' == ACTAG_CODE_DOWNLOAD_DISABLED[0], "Assumption violated");
1352             Contract.Assert('D' == ACTAG_DISALLOW_APP_BINDING_REDIRECTS[0], "Assumption violated");
1353             Contract.Assert('D' == ACTAG_DISALLOW_APP_BASE_PROBING[0], "Assumption violated");
1354             Contract.Assert('A' == ACTAG_APP_CONFIG_BLOB[0], "Assumption violated");
1355
1356             switch (s[0]) {
1357                 case 'A':
1358                     if (s == ACTAG_APP_CONFIG_FILE)     return (int)LoaderInformation.ConfigurationFileValue;
1359                     if (s == ACTAG_APP_NAME)            return (int)LoaderInformation.ApplicationNameValue;
1360                     if (s == ACTAG_APP_BASE_URL)        return (int)LoaderInformation.ApplicationBaseValue;
1361                     if (s == ACTAG_APP_CONFIG_BLOB)     return (int)LoaderInformation.ConfigurationBytesValue;
1362                     break;
1363                 case 'B':
1364                     if (s == ACTAG_BINPATH_PROBE_ONLY)  return (int)LoaderInformation.PrivateBinPathProbeValue;
1365                     break;
1366                 case 'C':
1367                     if (s == ACTAG_APP_CACHE_BASE)      return (int)LoaderInformation.CachePathValue;
1368                     if (s == ACTAG_CODE_DOWNLOAD_DISABLED) return (int)LoaderInformation.DisallowCodeDownloadValue;
1369                     break;
1370                 case 'D':
1371                     if (s == ACTAG_DEV_PATH)            return (int)LoaderInformation.DevPathValue;
1372                     if (s == ACTAG_APP_DYNAMIC_BASE)    return (int)LoaderInformation.DynamicBaseValue;
1373                     if (s == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY) return (int)LoaderInformation.DisallowPublisherPolicyValue;
1374                     if (s == ACTAG_DISALLOW_APP_BINDING_REDIRECTS) return (int)LoaderInformation.DisallowBindingRedirectsValue;
1375                     if (s == ACTAG_DISALLOW_APP_BASE_PROBING) return (int)LoaderInformation.DisallowAppBaseProbingValue;
1376                    break;
1377                 case 'F':
1378                     if (s == ACTAG_FORCE_CACHE_INSTALL) return (int)LoaderInformation.ShadowCopyFilesValue;
1379                     break;
1380                 case 'L':
1381                     if (s == LICENSE_FILE)              return (int)LoaderInformation.LicenseFileValue;
1382                     break;
1383                 case 'P':
1384                     if (s == ACTAG_APP_PRIVATE_BINPATH) return (int)LoaderInformation.PrivateBinPathValue;
1385                     break;
1386                 case 'S':
1387                     if (s == ACTAG_APP_SHADOW_COPY_DIRS) return (int)LoaderInformation.ShadowCopyDirectoriesValue;
1388                     break;
1389             }
1390 #else
1391             Contract.Assert('A' == ACTAG_APP_BASE_URL[0]        , "Assumption violated");
1392             if (s[0]=='A' && s == ACTAG_APP_BASE_URL)        
1393                 return (int)LoaderInformation.ApplicationBaseValue;
1394
1395 #endif //FEATURE_FUSION
1396
1397             return -1;
1398         }
1399 #if FEATURE_FUSION
1400         private string BuildShadowCopyDirectories()
1401         {
1402             // Default to only to the ones that are in the private bin path.
1403             String binPath = Value[(int) LoaderInformation.PrivateBinPathValue];
1404             if(binPath == null)
1405                 return null;
1406
1407             StringBuilder result = StringBuilderCache.Acquire();
1408             String appBase = Value[(int) LoaderInformation.ApplicationBaseValue];
1409             if(appBase != null) {
1410                 char[] sep = {';'};
1411                 string[] directories = binPath.Split(sep);
1412                 int size = directories.Length;
1413                 bool appendSlash = !( (appBase[appBase.Length-1] == '/') ||
1414                                       (appBase[appBase.Length-1] == '\\') );
1415
1416                 if (size == 0) {
1417                     result.Append(appBase);
1418                     if (appendSlash)
1419                         result.Append('\\');
1420                     result.Append(binPath);
1421                 }
1422                 else {
1423                     for(int i = 0; i < size; i++) {
1424                         result.Append(appBase);
1425                         if (appendSlash)
1426                             result.Append('\\');
1427                         result.Append(directories[i]);
1428                         
1429                         if (i < size-1)
1430                             result.Append(';');
1431                     }
1432                 }
1433             }
1434             
1435             return StringBuilderCache.GetStringAndRelease(result);
1436         }
1437 #endif // FEATURE_FUSION                
1438
1439 #if FEATURE_COMINTEROP
1440         public bool SandboxInterop
1441         {
1442             get
1443             {
1444                 return _DisableInterfaceCache;
1445             }
1446             set
1447             {
1448                 _DisableInterfaceCache = value;
1449             }
1450         }
1451 #endif // FEATURE_COMINTEROP
1452     }
1453 }