|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*=============================================================================
**
** Class: AppDomainSetup
**
** <OWNER>blanders</OWNER>
**
** Purpose: Defines the settings that the loader uses to find assemblies in an
** AppDomain
**
** Date: Dec 22, 2000
**
=============================================================================*/
namespace System {
using System;
#if FEATURE_CLICKONCE
#if !FEATURE_PAL
using System.Deployment.Internal.Isolation;
using System.Deployment.Internal.Isolation.Manifest;
using System.Runtime.Hosting;
#endif
#endif
using System.Runtime.CompilerServices;
using System.Runtime;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Globalization;
using Path = System.IO.Path;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
using System.Collections;
using System.Collections.Generic;
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class AppDomainSetup :
IAppDomainSetup
{
[Serializable]
internal enum LoaderInformation
{
// If you add a new value, add the corresponding property
// to AppDomain.GetData() and SetData()'s switch statements.
ApplicationBaseValue = LOADER_APPLICATION_BASE,
ConfigurationFileValue = LOADER_CONFIGURATION_BASE,
DynamicBaseValue = LOADER_DYNAMIC_BASE,
DevPathValue = LOADER_DEVPATH,
ApplicationNameValue = LOADER_APPLICATION_NAME,
PrivateBinPathValue = LOADER_PRIVATE_PATH,
PrivateBinPathProbeValue = LOADER_PRIVATE_BIN_PATH_PROBE,
ShadowCopyDirectoriesValue = LOADER_SHADOW_COPY_DIRECTORIES,
ShadowCopyFilesValue = LOADER_SHADOW_COPY_FILES,
CachePathValue = LOADER_CACHE_PATH,
LicenseFileValue = LOADER_LICENSE_FILE,
DisallowPublisherPolicyValue = LOADER_DISALLOW_PUBLISHER_POLICY,
DisallowCodeDownloadValue = LOADER_DISALLOW_CODE_DOWNLOAD,
DisallowBindingRedirectsValue = LOADER_DISALLOW_BINDING_REDIRECTS,
DisallowAppBaseProbingValue = LOADER_DISALLOW_APPBASE_PROBING,
ConfigurationBytesValue = LOADER_CONFIGURATION_BYTES,
LoaderMaximum = LOADER_MAXIMUM,
}
// This class has an unmanaged representation so be aware you will need to make edits in vm\object.h if you change the order
// of these fields or add new ones.
private string[] _Entries;
private LoaderOptimization _LoaderOptimization;
#pragma warning disable 169
private String _AppBase; // for compat with v1.1
#pragma warning restore 169
[OptionalField(VersionAdded = 2)]
private AppDomainInitializer _AppDomainInitializer;
[OptionalField(VersionAdded = 2)]
private string[] _AppDomainInitializerArguments;
#if FEATURE_CLICKONCE
[OptionalField(VersionAdded = 2)]
private ActivationArguments _ActivationArguments;
#endif
#if FEATURE_CORECLR
// On the CoreCLR, this contains just the name of the permission set that we install in the new appdomain.
// Not the ToXml().ToString() of an ApplicationTrust object.
#endif
[OptionalField(VersionAdded = 2)]
private string _ApplicationTrust;
[OptionalField(VersionAdded = 2)]
private byte[] _ConfigurationBytes;
#if FEATURE_COMINTEROP
[OptionalField(VersionAdded = 3)]
private bool _DisableInterfaceCache = false;
#endif // FEATURE_COMINTEROP
[OptionalField(VersionAdded = 4)]
private string _AppDomainManagerAssembly;
[OptionalField(VersionAdded = 4)]
private string _AppDomainManagerType;
#if FEATURE_APTCA
[OptionalField(VersionAdded = 4)]
private string[] _AptcaVisibleAssemblies;
#endif
// A collection of strings used to indicate which breaking changes shouldn't be applied
// to an AppDomain. We only use the keys, the values are ignored.
[OptionalField(VersionAdded = 4)]
private Dictionary<string, object> _CompatFlags;
[OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
private String _TargetFrameworkName;
#if !FEATURE_CORECLR
[NonSerialized]
internal AppDomainSortingSetupInfo _AppDomainSortingSetupInfo;
#endif
[OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
private bool _CheckedForTargetFrameworkName;
#if FEATURE_RANDOMIZED_STRING_HASHING
[OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
private bool _UseRandomizedStringHashing;
#endif
[SecuritySafeCritical]
internal AppDomainSetup(AppDomainSetup copy, bool copyDomainBoundData)
{
string[] mine = Value;
if(copy != null) {
string[] other = copy.Value;
int mineSize = _Entries.Length;
int otherSize = other.Length;
int size = (otherSize < mineSize) ? otherSize : mineSize;
for (int i = 0; i < size; i++)
mine[i] = other[i];
if (size < mineSize)
{
// This case can happen when the copy is a deserialized version of
// an AppDomainSetup object serialized by Everett.
for (int i = size; i < mineSize; i++)
mine[i] = null;
}
_LoaderOptimization = copy._LoaderOptimization;
_AppDomainInitializerArguments = copy.AppDomainInitializerArguments;
#if FEATURE_CLICKONCE
_ActivationArguments = copy.ActivationArguments;
#endif
_ApplicationTrust = copy._ApplicationTrust;
if (copyDomainBoundData)
_AppDomainInitializer = copy.AppDomainInitializer;
else
_AppDomainInitializer = null;
_ConfigurationBytes = copy.GetConfigurationBytes();
#if FEATURE_COMINTEROP
_DisableInterfaceCache = copy._DisableInterfaceCache;
#endif // FEATURE_COMINTEROP
_AppDomainManagerAssembly = copy.AppDomainManagerAssembly;
_AppDomainManagerType = copy.AppDomainManagerType;
#if FEATURE_APTCA
_AptcaVisibleAssemblies = copy.PartialTrustVisibleAssemblies;
#endif
if (copy._CompatFlags != null)
{
SetCompatibilitySwitches(copy._CompatFlags.Keys);
}
#if !FEATURE_CORECLR
if(copy._AppDomainSortingSetupInfo != null)
{
_AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo(copy._AppDomainSortingSetupInfo);
}
#endif
_TargetFrameworkName = copy._TargetFrameworkName;
#if FEATURE_RANDOMIZED_STRING_HASHING
_UseRandomizedStringHashing = copy._UseRandomizedStringHashing;
#endif
}
else
_LoaderOptimization = LoaderOptimization.NotSpecified;
}
public AppDomainSetup()
{
_LoaderOptimization = LoaderOptimization.NotSpecified;
}
#if FEATURE_CLICKONCE
// Creates an AppDomainSetup object from an application identity.
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public AppDomainSetup (ActivationContext activationContext) : this (new ActivationArguments(activationContext)) {}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
public AppDomainSetup (ActivationArguments activationArguments) {
if (activationArguments == null)
throw new ArgumentNullException("activationArguments");
Contract.EndContractBlock();
_LoaderOptimization = LoaderOptimization.NotSpecified;
ActivationArguments = activationArguments;
Contract.Assert(activationArguments.ActivationContext != null, "Cannot set base directory without activation context");
string entryPointPath = CmsUtils.GetEntryPointFullPath(activationArguments);
if (!String.IsNullOrEmpty(entryPointPath))
SetupDefaults(entryPointPath);
else
ApplicationBase = activationArguments.ActivationContext.ApplicationDirectory;
}
#endif // !FEATURE_CLICKONCE
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
internal void SetupDefaults(string imageLocation, bool imageLocationAlreadyNormalized = false) {
char[] sep = {'\\', '/'};
int i = imageLocation.LastIndexOfAny(sep);
if (i == -1) {
ApplicationName = imageLocation;
}
else {
ApplicationName = imageLocation.Substring(i+1);
string appBase = imageLocation.Substring(0, i+1);
if (imageLocationAlreadyNormalized)
Value[(int) LoaderInformation.ApplicationBaseValue] = appBase;
else
ApplicationBase = appBase;
}
ConfigurationFile = ApplicationName + AppDomainSetup.ConfigurationExtension;
}
internal string[] Value
{
get {
if( _Entries == null)
_Entries = new String[LOADER_MAXIMUM];
return _Entries;
}
}
internal String GetUnsecureApplicationBase()
{
return Value[(int) LoaderInformation.ApplicationBaseValue];
}
public string AppDomainManagerAssembly
{
get { return _AppDomainManagerAssembly; }
set { _AppDomainManagerAssembly = value; }
}
public string AppDomainManagerType
{
get { return _AppDomainManagerType; }
set { _AppDomainManagerType = value; }
}
#if FEATURE_APTCA
public string[] PartialTrustVisibleAssemblies
{
get { return _AptcaVisibleAssemblies; }
set {
if (value != null) {
_AptcaVisibleAssemblies = (string[])value.Clone();
Array.Sort<string>(_AptcaVisibleAssemblies, StringComparer.OrdinalIgnoreCase);
}
else {
_AptcaVisibleAssemblies = null;
}
}
}
#endif
public String ApplicationBase
{
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[Pure]
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return VerifyDir(GetUnsecureApplicationBase(), false);
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.ApplicationBaseValue] = NormalizePath(value, false);
}
}
[System.Security.SecuritySafeCritical]
private string NormalizePath(string path, bool useAppBase)
{
if(path == null)
return null;
// If we add very long file name support ("\\?\") to the Path class then this is unnecesary,
// but we do not plan on doing this for now.
// Long path checks can be quirked, and as loading default quirks too early in the setup of an AppDomain is risky
// we'll avoid checking path lengths- we'll still fail at MAX_PATH later if we're !useAppBase when we call Path's
// NormalizePath.
if (!useAppBase)
path = System.Security.Util.URLString.PreProcessForExtendedPathRemoval(
checkPathLength: false,
url: path,
isFileUrl: false);
int len = path.Length;
if (len == 0)
return null;
bool UNCpath = false;
if ((len > 7) &&
(String.Compare( path, 0, "file:", 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) {
int trim;
if (path[6] == '\\') {
if ((path[7] == '\\') || (path[7] == '/')) {
// Don't allow "file:\\\\", because we can't tell the difference
// with it for "file:\\" + "\\server" and "file:\\\" + "\localpath"
if ( (len > 8) &&
((path[8] == '\\') || (path[8] == '/')) )
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
// file:\\\ means local path
else
trim = 8;
}
// file:\\ means remote server
else {
trim = 5;
UNCpath = true;
}
}
// local path
else if (path[7] == '/')
trim = 8;
// remote
else {
// file://\\remote
if ( (len > 8) && (path[7] == '\\') && (path[8] == '\\') )
trim = 7;
else { // file://remote
trim = 5;
// Create valid UNC path by changing
// all occurences of '/' to '\\' in path
System.Text.StringBuilder winPathBuilder =
new System.Text.StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = path[i];
if (c == '/')
winPathBuilder.Append('\\');
else
winPathBuilder.Append(c);
}
path = winPathBuilder.ToString();
}
UNCpath = true;
}
path = path.Substring(trim);
len -= trim;
}
bool localPath;
// UNC
if (UNCpath ||
( (len > 1) &&
( (path[0] == '/') || (path[0] == '\\') ) &&
( (path[1] == '/') || (path[1] == '\\') ) ))
localPath = false;
else {
int colon = path.IndexOf(':') + 1;
// protocol other than file:
if ((colon != 0) &&
(len > colon+1) &&
( (path[colon] == '/') || (path[colon] == '\\') ) &&
( (path[colon+1] == '/') || (path[colon+1] == '\\') ))
localPath = false;
else
localPath = true;
}
if (localPath)
{
if (useAppBase &&
((len == 1) || (path[1] != ':')))
{
String appBase = Value[(int)LoaderInformation.ApplicationBaseValue];
if ((appBase == null) || (appBase.Length == 0))
throw new MemberAccessException(Environment.GetResourceString("AppDomain_AppBaseNotSet"));
StringBuilder result = StringBuilderCache.Acquire();
bool slash = false;
if ((path[0] == '/') || (path[0] == '\\')) {
// Emulate Path.GetPathRoot without hitting code paths that check quirks
string pathRoot = AppDomain.NormalizePath(appBase, fullCheck: false);
pathRoot = pathRoot.Substring(0, System.IO.PathInternal.GetRootLength(pathRoot));
if (pathRoot.Length == 0) { // URL
int index = appBase.IndexOf(":/", StringComparison.Ordinal);
if (index == -1)
index = appBase.IndexOf(":\\", StringComparison.Ordinal);
// Get past last slashes of "url:http://"
int urlLen = appBase.Length;
for (index += 1;
(index < urlLen) && ((appBase[index] == '/') || (appBase[index] == '\\'));
index++) ;
// Now find the next slash to get domain name
for (; (index < urlLen) && (appBase[index] != '/') && (appBase[index] != '\\');
index++) ;
pathRoot = appBase.Substring(0, index);
}
result.Append(pathRoot);
slash = true;
}
else
result.Append(appBase);
// Make sure there's a slash separator (and only one)
int aLen = result.Length - 1;
if ((result[aLen] != '/') &&
(result[aLen] != '\\')) {
if (!slash) {
if (appBase.IndexOf(":/", StringComparison.Ordinal) == -1)
result.Append('\\');
else
result.Append('/');
}
}
else if (slash)
result.Remove(aLen, 1);
result.Append(path);
path = StringBuilderCache.GetStringAndRelease(result);
}
else
{
path = AppDomain.NormalizePath(path, fullCheck: true);
}
}
return path;
}
private bool IsFilePath(String path)
{
return (path[1] == ':') || ( (path[0] == '\\') && (path[1] == '\\') );
}
internal static String ApplicationBaseKey
{
get {
return ACTAG_APP_BASE_URL;
}
}
public String ConfigurationFile
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return VerifyDir(Value[(int) LoaderInformation.ConfigurationFileValue], true);
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.ConfigurationFileValue] = value;
}
}
// Used by the ResourceManager internally. This must not do any
// security checks to avoid infinite loops.
internal String ConfigurationFileInternal
{
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return NormalizePath(Value[(int) LoaderInformation.ConfigurationFileValue], true);
}
}
internal static String ConfigurationFileKey
{
get {
return ACTAG_APP_CONFIG_FILE;
}
}
public byte[] GetConfigurationBytes()
{
if (_ConfigurationBytes == null)
return null;
return (byte[]) _ConfigurationBytes.Clone();
}
public void SetConfigurationBytes(byte[] value)
{
_ConfigurationBytes = value;
}
private static String ConfigurationBytesKey
{
get {
return ACTAG_APP_CONFIG_BLOB;
}
}
// only needed by AppDomain.Setup(). Not really needed by users.
internal Dictionary<string, object> GetCompatibilityFlags()
{
return _CompatFlags;
}
public void SetCompatibilitySwitches(IEnumerable<String> switches)
{
#if !FEATURE_CORECLR
if(_AppDomainSortingSetupInfo != null)
{
_AppDomainSortingSetupInfo._useV2LegacySorting = false;
_AppDomainSortingSetupInfo._useV4LegacySorting = false;
}
#endif
#if FEATURE_RANDOMIZED_STRING_HASHING
_UseRandomizedStringHashing = false;
#endif
if (switches != null)
{
_CompatFlags = new Dictionary<string, object>();
foreach (String str in switches)
{
#if !FEATURE_CORECLR
if(StringComparer.OrdinalIgnoreCase.Equals("NetFx40_Legacy20SortingBehavior", str)) {
if(_AppDomainSortingSetupInfo == null)
{
_AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
}
_AppDomainSortingSetupInfo._useV2LegacySorting = true;
}
if(StringComparer.OrdinalIgnoreCase.Equals("NetFx45_Legacy40SortingBehavior", str)) {
if(_AppDomainSortingSetupInfo == null)
{
_AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
}
_AppDomainSortingSetupInfo._useV4LegacySorting = true;
}
#endif
#if FEATURE_RANDOMIZED_STRING_HASHING
if(StringComparer.OrdinalIgnoreCase.Equals("UseRandomizedStringHashAlgorithm", str)) {
_UseRandomizedStringHashing = true;
}
#endif
_CompatFlags.Add(str, null);
}
}
else
{
_CompatFlags = null;
}
}
// A target Framework moniker, in a format parsible by the FrameworkName class.
public String TargetFrameworkName {
get {
return _TargetFrameworkName;
}
set {
_TargetFrameworkName = value;
}
}
internal bool CheckedForTargetFrameworkName
{
get { return _CheckedForTargetFrameworkName; }
set { _CheckedForTargetFrameworkName = value; }
}
#if !FEATURE_CORECLR
[SecurityCritical]
public void SetNativeFunction(string functionName, int functionVersion, IntPtr functionPointer)
{
if(functionName == null)
{
throw new ArgumentNullException("functionName");
}
if(functionPointer == IntPtr.Zero)
{
throw new ArgumentNullException("functionPointer");
}
if(String.IsNullOrWhiteSpace(functionName))
{
throw new ArgumentException(Environment.GetResourceString("Argument_NPMSInvalidName"), "functionName");
}
Contract.EndContractBlock();
if(functionVersion < 1)
{
throw new ArgumentException(Environment.GetResourceString("ArgumentException_MinSortingVersion", 1, functionName));
}
if(_AppDomainSortingSetupInfo == null)
{
_AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
}
if(String.Equals(functionName, "IsNLSDefinedString", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnIsNLSDefinedString = functionPointer;
}
if (String.Equals(functionName, "CompareStringEx", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnCompareStringEx = functionPointer;
}
if (String.Equals(functionName, "LCMapStringEx", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnLCMapStringEx = functionPointer;
}
if (String.Equals(functionName, "FindNLSStringEx", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnFindNLSStringEx = functionPointer;
}
if (String.Equals(functionName, "CompareStringOrdinal", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnCompareStringOrdinal = functionPointer;
}
if (String.Equals(functionName, "GetNLSVersionEx", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnGetNLSVersionEx = functionPointer;
}
if (String.Equals(functionName, "FindStringOrdinal", StringComparison.OrdinalIgnoreCase))
{
_AppDomainSortingSetupInfo._pfnFindStringOrdinal = functionPointer;
}
}
#endif
public String DynamicBase
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return VerifyDir(Value[(int) LoaderInformation.DynamicBaseValue], true);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
if (value == null)
Value[(int) LoaderInformation.DynamicBaseValue] = null;
else {
if(ApplicationName == null)
throw new MemberAccessException(Environment.GetResourceString("AppDomain_RequireApplicationName"));
StringBuilder s = new StringBuilder( NormalizePath(value, false) );
s.Append('\\');
string h = ParseNumbers.IntToString(ApplicationName.GetLegacyNonRandomizedHashCode(),
16, 8, '0', ParseNumbers.PrintAsI4);
s.Append(h);
Value[(int) LoaderInformation.DynamicBaseValue] = s.ToString();
}
}
}
internal static String DynamicBaseKey
{
get {
return ACTAG_APP_DYNAMIC_BASE;
}
}
public bool DisallowPublisherPolicy
{
get
{
return (Value[(int) LoaderInformation.DisallowPublisherPolicyValue] != null);
}
set
{
if (value)
Value[(int) LoaderInformation.DisallowPublisherPolicyValue]="true";
else
Value[(int) LoaderInformation.DisallowPublisherPolicyValue]=null;
}
}
public bool DisallowBindingRedirects
{
get
{
return (Value[(int) LoaderInformation.DisallowBindingRedirectsValue] != null);
}
set
{
if (value)
Value[(int) LoaderInformation.DisallowBindingRedirectsValue] = "true";
else
Value[(int) LoaderInformation.DisallowBindingRedirectsValue] = null;
}
}
public bool DisallowCodeDownload
{
get
{
return (Value[(int) LoaderInformation.DisallowCodeDownloadValue] != null);
}
set
{
if (value)
Value[(int) LoaderInformation.DisallowCodeDownloadValue] = "true";
else
Value[(int) LoaderInformation.DisallowCodeDownloadValue] = null;
}
}
public bool DisallowApplicationBaseProbing
{
get
{
return (Value[(int) LoaderInformation.DisallowAppBaseProbingValue] != null);
}
set
{
if (value)
Value[(int) LoaderInformation.DisallowAppBaseProbingValue] = "true";
else
Value[(int) LoaderInformation.DisallowAppBaseProbingValue] = null;
}
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
private String VerifyDir(String dir, bool normalize)
{
if (dir != null)
{
if (dir.Length == 0)
{
dir = null;
}
else
{
if (normalize)
dir = NormalizePath(dir, true);
// The only way AppDomainSetup is exposed in coreclr is through the AppDomainManager
// and the AppDomainManager is a SecurityCritical type. Also, all callers of callstacks
// leading from VerifyDir are SecurityCritical. So we can remove the Demand because
// we have validated that all callers are SecurityCritical
#if !FEATURE_CORECLR
if (IsFilePath(dir))
{
// If we've already normalized we don't need to do it again, and can avoid hitting
// quirks in FileIOPermission.
new FileIOPermission(
access: FileIOPermissionAccess.PathDiscovery,
pathList: new string[] { dir },
checkForDuplicates: false,
needFullPath: false).Demand();
}
#endif // !FEATURE_CORECLR
}
}
return dir;
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
private void VerifyDirList(String dirs)
{
if (dirs != null) {
String[] dirArray = dirs.Split(';');
int len = dirArray.Length;
for (int i = 0; i < len; i++)
VerifyDir(dirArray[i], true);
}
}
internal String DeveloperPath
{
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
String dirs = Value[(int) LoaderInformation.DevPathValue];
VerifyDirList(dirs);
return dirs;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
if(value == null)
Value[(int) LoaderInformation.DevPathValue] = null;
else {
String[] directories = value.Split(';');
int size = directories.Length;
StringBuilder newPath = StringBuilderCache.Acquire();
bool fDelimiter = false;
for(int i = 0; i < size; i++) {
if(directories[i].Length != 0) {
if(fDelimiter)
newPath.Append(";");
else
fDelimiter = true;
newPath.Append(Path.GetFullPathInternal(directories[i]));
}
}
String newString = StringBuilderCache.GetStringAndRelease(newPath);
if (newString.Length == 0)
Value[(int) LoaderInformation.DevPathValue] = null;
else
Value[(int) LoaderInformation.DevPathValue] = newString;
}
}
}
internal static String DisallowPublisherPolicyKey
{
get
{
return ACTAG_DISALLOW_APPLYPUBLISHERPOLICY;
}
}
internal static String DisallowCodeDownloadKey
{
get
{
return ACTAG_CODE_DOWNLOAD_DISABLED;
}
}
internal static String DisallowBindingRedirectsKey
{
get
{
return ACTAG_DISALLOW_APP_BINDING_REDIRECTS;
}
}
internal static String DeveloperPathKey
{
get {
return ACTAG_DEV_PATH;
}
}
internal static String DisallowAppBaseProbingKey
{
get
{
return ACTAG_DISALLOW_APP_BASE_PROBING;
}
}
public String ApplicationName
{
get {
return Value[(int) LoaderInformation.ApplicationNameValue];
}
set {
Value[(int) LoaderInformation.ApplicationNameValue] = value;
}
}
internal static String ApplicationNameKey
{
get {
return ACTAG_APP_NAME;
}
}
[XmlIgnoreMember]
public AppDomainInitializer AppDomainInitializer
{
get {
return _AppDomainInitializer;
}
set {
_AppDomainInitializer = value;
}
}
public string[] AppDomainInitializerArguments
{
get {
return _AppDomainInitializerArguments;
}
set {
_AppDomainInitializerArguments = value;
}
}
#if FEATURE_CLICKONCE
[XmlIgnoreMember]
public ActivationArguments ActivationArguments {
[Pure]
get {
return _ActivationArguments;
}
set {
_ActivationArguments = value;
}
}
#endif // !FEATURE_CLICKONCE
internal ApplicationTrust InternalGetApplicationTrust()
{
if (_ApplicationTrust == null) return null;
#if FEATURE_CORECLR
ApplicationTrust grantSet = new ApplicationTrust(NamedPermissionSet.GetBuiltInSet(_ApplicationTrust));
#else
SecurityElement securityElement = SecurityElement.FromString(_ApplicationTrust);
ApplicationTrust grantSet = new ApplicationTrust();
grantSet.FromXml(securityElement);
#endif
return grantSet;
}
#if FEATURE_CORECLR
internal void InternalSetApplicationTrust(String permissionSetName)
{
_ApplicationTrust = permissionSetName;
}
#else
internal void InternalSetApplicationTrust(ApplicationTrust value)
{
if (value != null)
{
_ApplicationTrust = value.ToXml().ToString();
}
else
{
_ApplicationTrust = null;
}
}
#endif
#if FEATURE_CLICKONCE
[XmlIgnoreMember]
public ApplicationTrust ApplicationTrust
{
get {
return InternalGetApplicationTrust();
}
set {
InternalSetApplicationTrust(value);
}
}
#else // FEATURE_CLICKONCE
[XmlIgnoreMember]
internal ApplicationTrust ApplicationTrust
{
get {
return InternalGetApplicationTrust();
}
#if !FEATURE_CORECLR
set {
InternalSetApplicationTrust(value);
}
#endif
}
#endif // FEATURE_CLICKONCE
public String PrivateBinPath
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
String dirs = Value[(int) LoaderInformation.PrivateBinPathValue];
VerifyDirList(dirs);
return dirs;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.PrivateBinPathValue] = value;
}
}
internal static String PrivateBinPathKey
{
get {
return ACTAG_APP_PRIVATE_BINPATH;
}
}
public String PrivateBinPathProbe
{
get {
return Value[(int) LoaderInformation.PrivateBinPathProbeValue];
}
set {
Value[(int) LoaderInformation.PrivateBinPathProbeValue] = value;
}
}
internal static String PrivateBinPathProbeKey
{
get {
return ACTAG_BINPATH_PROBE_ONLY;
}
}
public String ShadowCopyDirectories
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
String dirs = Value[(int) LoaderInformation.ShadowCopyDirectoriesValue];
VerifyDirList(dirs);
return dirs;
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.ShadowCopyDirectoriesValue] = value;
}
}
internal static String ShadowCopyDirectoriesKey
{
get {
return ACTAG_APP_SHADOW_COPY_DIRS;
}
}
public String ShadowCopyFiles
{
get {
return Value[(int) LoaderInformation.ShadowCopyFilesValue];
}
set {
if((value != null) &&
(String.Compare(value, "true", StringComparison.OrdinalIgnoreCase) == 0))
Value[(int) LoaderInformation.ShadowCopyFilesValue] = value;
else
Value[(int) LoaderInformation.ShadowCopyFilesValue] = null;
}
}
internal static String ShadowCopyFilesKey
{
get {
return ACTAG_FORCE_CACHE_INSTALL;
}
}
public String CachePath
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return VerifyDir(Value[(int) LoaderInformation.CachePathValue], false);
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.CachePathValue] = NormalizePath(value, false);
}
}
internal static String CachePathKey
{
get {
return ACTAG_APP_CACHE_BASE;
}
}
public String LicenseFile
{
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
get {
return VerifyDir(Value[(int) LoaderInformation.LicenseFileValue], true);
}
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
set {
Value[(int) LoaderInformation.LicenseFileValue] = value;
}
}
public LoaderOptimization LoaderOptimization
{
get {
return _LoaderOptimization;
}
set {
_LoaderOptimization = value;
}
}
internal static string LoaderOptimizationKey
{
get {
return LOADER_OPTIMIZATION;
}
}
internal static string ConfigurationExtension
{
get {
return CONFIGURATION_EXTENSION;
}
}
internal static String PrivateBinPathEnvironmentVariable
{
get {
return APPENV_RELATIVEPATH;
}
}
internal static string RuntimeConfigurationFile
{
get {
return MACHINE_CONFIGURATION_FILE;
}
}
internal static string MachineConfigKey
{
get {
return ACTAG_MACHINE_CONFIG;
}
}
internal static string HostBindingKey
{
get {
return ACTAG_HOST_CONFIG_FILE;
}
}
#if FEATURE_FUSION
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal bool UpdateContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, String UpdatedField, IntPtr fusionContext, AppDomainSetup oldADS)
{
String FieldString = Value[(int) FieldValue],
OldFieldString = (oldADS == null ? null : oldADS.Value[(int) FieldValue]);
if (FieldString != OldFieldString) { // Compare references since strings are immutable
UpdateContextProperty(fusionContext, FieldKey, UpdatedField == null ? FieldString : UpdatedField);
return true;
}
return false;
}
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal void UpdateBooleanContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, IntPtr fusionContext, AppDomainSetup oldADS)
{
if (Value[(int) FieldValue] != null)
UpdateContextProperty(fusionContext, FieldKey, "true");
else if (oldADS != null && oldADS.Value[(int) FieldValue] != null)
UpdateContextProperty(fusionContext, FieldKey, "false");
}
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal static bool ByteArraysAreDifferent(Byte[] A, Byte[] B)
{
int length = A.Length;
if (length != B.Length)
return true;
for(int i = 0; i < length; i++) {
if (A[i] != B[i])
return true;
}
return false;
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal static void UpdateByteArrayContextPropertyIfNeeded(Byte[] NewArray, Byte[] OldArray, String FieldKey, IntPtr fusionContext)
{
if ((NewArray != null && OldArray == null) ||
(NewArray == null && OldArray != null) ||
(NewArray != null && OldArray != null && ByteArraysAreDifferent(NewArray, OldArray)))
UpdateContextProperty(fusionContext, FieldKey, NewArray);
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
internal void SetupFusionContext(IntPtr fusionContext, AppDomainSetup oldADS)
{
UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationBaseValue, ApplicationBaseKey, null, fusionContext, oldADS);
UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathValue, PrivateBinPathKey, null, fusionContext, oldADS);
UpdateContextPropertyIfNeeded(LoaderInformation.DevPathValue, DeveloperPathKey, null, fusionContext, oldADS);
UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowPublisherPolicyValue, DisallowPublisherPolicyKey, fusionContext, oldADS);
UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowCodeDownloadValue, DisallowCodeDownloadKey, fusionContext, oldADS);
UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowBindingRedirectsValue, DisallowBindingRedirectsKey, fusionContext, oldADS);
UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowAppBaseProbingValue, DisallowAppBaseProbingKey, fusionContext, oldADS);
if(UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyFilesValue, ShadowCopyFilesKey, ShadowCopyFiles, fusionContext, oldADS)) {
// If we are asking for shadow copy directories then default to
// only to the ones that are in the private bin path.
if(Value[(int) LoaderInformation.ShadowCopyDirectoriesValue] == null)
ShadowCopyDirectories = BuildShadowCopyDirectories();
UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyDirectoriesValue, ShadowCopyDirectoriesKey, null, fusionContext, oldADS);
}
UpdateContextPropertyIfNeeded(LoaderInformation.CachePathValue, CachePathKey, null, fusionContext, oldADS);
UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathProbeValue, PrivateBinPathProbeKey, PrivateBinPathProbe, fusionContext, oldADS);
UpdateContextPropertyIfNeeded(LoaderInformation.ConfigurationFileValue, ConfigurationFileKey, null, fusionContext, oldADS);
UpdateByteArrayContextPropertyIfNeeded(_ConfigurationBytes, oldADS == null ? null : oldADS.GetConfigurationBytes(), ConfigurationBytesKey, fusionContext);
UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationNameValue, ApplicationNameKey, ApplicationName, fusionContext, oldADS);
UpdateContextPropertyIfNeeded(LoaderInformation.DynamicBaseValue, DynamicBaseKey, null, fusionContext, oldADS);
// Always add the runtime configuration file to the appdomain
UpdateContextProperty(fusionContext, MachineConfigKey, RuntimeEnvironment.GetRuntimeDirectoryImpl() + RuntimeConfigurationFile);
String hostBindingFile = RuntimeEnvironment.GetHostBindingFile();
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.
UpdateContextProperty(fusionContext, HostBindingKey, hostBindingFile);
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void UpdateContextProperty(IntPtr fusionContext, string key, Object value);
#endif // FEATURE_FUSION
static internal int Locate(String s)
{
if(String.IsNullOrEmpty(s))
return -1;
#if FEATURE_FUSION
// verify assumptions hardcoded into the switch below
Contract.Assert('A' == ACTAG_APP_CONFIG_FILE[0] , "Assumption violated");
Contract.Assert('A' == ACTAG_APP_NAME[0] , "Assumption violated");
Contract.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
Contract.Assert('B' == ACTAG_BINPATH_PROBE_ONLY[0] , "Assumption violated");
Contract.Assert('C' == ACTAG_APP_CACHE_BASE[0] , "Assumption violated");
Contract.Assert('D' == ACTAG_DEV_PATH[0] , "Assumption violated");
Contract.Assert('D' == ACTAG_APP_DYNAMIC_BASE[0] , "Assumption violated");
Contract.Assert('F' == ACTAG_FORCE_CACHE_INSTALL[0] , "Assumption violated");
Contract.Assert('L' == LICENSE_FILE[0] , "Assumption violated");
Contract.Assert('P' == ACTAG_APP_PRIVATE_BINPATH[0] , "Assumption violated");
Contract.Assert('S' == ACTAG_APP_SHADOW_COPY_DIRS[0], "Assumption violated");
Contract.Assert('D' == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY[0], "Assumption violated");
Contract.Assert('C' == ACTAG_CODE_DOWNLOAD_DISABLED[0], "Assumption violated");
Contract.Assert('D' == ACTAG_DISALLOW_APP_BINDING_REDIRECTS[0], "Assumption violated");
Contract.Assert('D' == ACTAG_DISALLOW_APP_BASE_PROBING[0], "Assumption violated");
Contract.Assert('A' == ACTAG_APP_CONFIG_BLOB[0], "Assumption violated");
switch (s[0]) {
case 'A':
if (s == ACTAG_APP_CONFIG_FILE) return (int)LoaderInformation.ConfigurationFileValue;
if (s == ACTAG_APP_NAME) return (int)LoaderInformation.ApplicationNameValue;
if (s == ACTAG_APP_BASE_URL) return (int)LoaderInformation.ApplicationBaseValue;
if (s == ACTAG_APP_CONFIG_BLOB) return (int)LoaderInformation.ConfigurationBytesValue;
break;
case 'B':
if (s == ACTAG_BINPATH_PROBE_ONLY) return (int)LoaderInformation.PrivateBinPathProbeValue;
break;
case 'C':
if (s == ACTAG_APP_CACHE_BASE) return (int)LoaderInformation.CachePathValue;
if (s == ACTAG_CODE_DOWNLOAD_DISABLED) return (int)LoaderInformation.DisallowCodeDownloadValue;
break;
case 'D':
if (s == ACTAG_DEV_PATH) return (int)LoaderInformation.DevPathValue;
if (s == ACTAG_APP_DYNAMIC_BASE) return (int)LoaderInformation.DynamicBaseValue;
if (s == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY) return (int)LoaderInformation.DisallowPublisherPolicyValue;
if (s == ACTAG_DISALLOW_APP_BINDING_REDIRECTS) return (int)LoaderInformation.DisallowBindingRedirectsValue;
if (s == ACTAG_DISALLOW_APP_BASE_PROBING) return (int)LoaderInformation.DisallowAppBaseProbingValue;
break;
case 'F':
if (s == ACTAG_FORCE_CACHE_INSTALL) return (int)LoaderInformation.ShadowCopyFilesValue;
break;
case 'L':
if (s == LICENSE_FILE) return (int)LoaderInformation.LicenseFileValue;
break;
case 'P':
if (s == ACTAG_APP_PRIVATE_BINPATH) return (int)LoaderInformation.PrivateBinPathValue;
break;
case 'S':
if (s == ACTAG_APP_SHADOW_COPY_DIRS) return (int)LoaderInformation.ShadowCopyDirectoriesValue;
break;
}
#else
Contract.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
if (s[0]=='A' && s == ACTAG_APP_BASE_URL)
return (int)LoaderInformation.ApplicationBaseValue;
#endif //FEATURE_FUSION
return -1;
}
#if FEATURE_FUSION
private string BuildShadowCopyDirectories()
{
// Default to only to the ones that are in the private bin path.
String binPath = Value[(int) LoaderInformation.PrivateBinPathValue];
if(binPath == null)
return null;
StringBuilder result = StringBuilderCache.Acquire();
String appBase = Value[(int) LoaderInformation.ApplicationBaseValue];
if(appBase != null) {
char[] sep = {';'};
string[] directories = binPath.Split(sep);
int size = directories.Length;
bool appendSlash = !( (appBase[appBase.Length-1] == '/') ||
(appBase[appBase.Length-1] == '\\') );
if (size == 0) {
result.Append(appBase);
if (appendSlash)
result.Append('\\');
result.Append(binPath);
}
else {
for(int i = 0; i < size; i++) {
result.Append(appBase);
if (appendSlash)
result.Append('\\');
result.Append(directories[i]);
if (i < size-1)
result.Append(';');
}
}
}
return StringBuilderCache.GetStringAndRelease(result);
}
#endif // FEATURE_FUSION
#if FEATURE_COMINTEROP
public bool SandboxInterop
{
get
{
return _DisableInterfaceCache;
}
set
{
_DisableInterfaceCache = value;
}
}
#endif // FEATURE_COMINTEROP
}
}
|