Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,51 @@
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
#if FEATURE_WIN_DB_APPCOMPAT
namespace System.Runtime.Versioning
{
public static class CompatibilitySwitch
{
/* This class contains two sets of api:
* 1. internal apis : These apis are supposed to be used by mscorlib.dll and other assemblies which use the <runtime> section in config
* These apis query for the value of quirk not only in windows quirk DB but also in runtime section of config files,
* registry and environment vars.
* 2. public apis : These apis are supposed to be used by FX assemblies which do not read the runtime section of config files and have
* have their own section in config files or do not use configs at all.
*
* These apis are for internal use only for FX assmeblies. It has not been decided if they can be used by OOB components due to EULA restrictions
*/
[System.Security.SecurityCritical]
public static bool IsEnabled(string compatibilitySwitchName)
{
return IsEnabledInternalCall(compatibilitySwitchName, true);
}
[System.Security.SecurityCritical]
public static string GetValue(string compatibilitySwitchName)
{
return GetValueInternalCall(compatibilitySwitchName, true);
}
[System.Security.SecurityCritical]
internal static bool IsEnabledInternal(string compatibilitySwitchName)
{
return IsEnabledInternalCall(compatibilitySwitchName, false);
}
[System.Security.SecurityCritical]
internal static string GetValueInternal(string compatibilitySwitchName)
{
return GetValueInternalCall(compatibilitySwitchName, false);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool IsEnabledInternalCall(string compatibilitySwitchName, bool onlyDB);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string GetValueInternalCall(string compatibilitySwitchName, bool onlyDB);
}
}
#endif

View File

@@ -0,0 +1,465 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: BinaryCompatibility
**
** <OWNER>[....]</OWNER>
**
**
** Purpose: This class is used to determine which binary compatibility
** behaviors are enabled at runtime. A type for
** tracking which target Framework an app was built against, or an
** appdomain-wide setting from the host telling us which .NET
** Framework version we should emulate.
**
**
===========================================================*/
using System;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace System.Runtime.Versioning
{
// Provides a simple way to test whether an application was built against specific .NET Framework
// flavors and versions, with the intent of allowing Framework developers to mimic behavior of older
// Framework releases. This allows us to make behavioral breaking changes in a binary compatible way,
// for an application. This works at the per-AppDomain level, not process nor per-Assembly.
//
// To opt into newer behavior, applications must specify a TargetFrameworkAttribute on their assembly
// saying what version they targeted, or a host must set this when creating an AppDomain. Note
// that command line apps don't have this attribute!
//
// To use this class:
// Developers need to figure out whether they're working on the phone, desktop, or Silverlight, and
// what version they are introducing a breaking change in. Pick one predicate below, and use that
// to decide whether to run the new or old behavior. Example:
//
// if (BinaryCompatibility.TargetsAtLeast_Phone_V7_1) {
// // new behavior for phone 7.1 and other releases where we will integrate this change, like .NET Framework 4.5
// }
// else {
// // Legacy behavior
// }
//
// If you are making a breaking change in one specific branch that won't be integrated normally to
// all other branches (ie, say you're making breaking changes to Windows Phone 8 after .NET Framework v4.5
// has locked down for release), then add in specific predicates for each relevant platform.
//
// Maintainers of this class:
// Revisit the table once per release, perhaps at the end of the last coding milestone, to verify a
// default policy saying whether all quirks from a particular flavor & release should be enabled in
// other releases (ie, should all Windows Phone 8.0 quirks be enabled in .NET Framework v5)?
//
// History:
// Here is the order in which releases were made along with some basic integration information. The idea
// is to track what set of compatibility features are present in each other.
// While we cannot guarantee this list is perfectly linear (ie, a feature could be implemented in the last
// few weeks before shipping and make it into only one of three concommittent releases due to triaging),
// this is a good high level summary of code flow.
//
// Desktop Silverlight Windows Phone
// .NET Framework 3.0 -> Silverlight 2
// .NET Framework 3.5
// Silverlight 3
// Silverlight 4
// .NET Framework 4
// Expected additions:
// .NET Framework 4.5 <-> Silverlight 5 <-> Phone 7.1
//
// (Note: Windows Phone 7.0 was built using the .NET Compact Framework, which forked around v1 or v1.1)
//
// Compatibility Policy decisions:
// If we cannot determine that an app was built for a newer .NET Framework (ie, the app has no
// TargetFrameworkAttribute), then quirks will be enabled to emulate older behavior.
// As such, your test code should define the TargetFrameworkAttribute (which VS does for you)
// if you want to see the new behavior!
[FriendAccessAllowed]
internal static class BinaryCompatibility
{
// Use this for new behavior introduced in the phone branch. It will do the right thing for desktop & SL.
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Phone_V7_1 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Phone_V7_1; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Phone_V8_0 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Phone_V8_0; } }
// Use this for new behavior introduced in the Desktop branch. It will do the right thing for Phone & SL.
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V4_5 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V4_5_1 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_1; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V4_5_2 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_2; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V4_5_3 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_3; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V4_5_4 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_4; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Desktop_V5_0 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V5_0; } }
// Use this for new behavior introduced in the Silverlight branch. It will do the right thing for desktop & Phone.
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Silverlight_V4 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V4; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Silverlight_V5 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V5; } }
[FriendAccessAllowed]
internal static bool TargetsAtLeast_Silverlight_V6 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V6; } }
[FriendAccessAllowed]
internal static TargetFrameworkId AppWasBuiltForFramework {
[FriendAccessAllowed]
get {
Contract.Ensures(Contract.Result<TargetFrameworkId>() > TargetFrameworkId.NotYetChecked);
if (s_AppWasBuiltForFramework == TargetFrameworkId.NotYetChecked)
ReadTargetFrameworkId();
return s_AppWasBuiltForFramework;
}
}
// Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
[FriendAccessAllowed]
internal static int AppWasBuiltForVersion {
[FriendAccessAllowed]
get {
Contract.Ensures(Contract.Result<int>() > 0 || s_AppWasBuiltForFramework == TargetFrameworkId.Unspecified);
if (s_AppWasBuiltForFramework == TargetFrameworkId.NotYetChecked)
ReadTargetFrameworkId();
Contract.Assert(s_AppWasBuiltForFramework != TargetFrameworkId.Unrecognized);
return s_AppWasBuiltForVersion;
}
}
#region private
private static TargetFrameworkId s_AppWasBuiltForFramework;
// Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
private static int s_AppWasBuiltForVersion;
readonly static BinaryCompatibilityMap s_map;
// Consider initializing the field directly instead of declaring a .cctor. There is a perf
// tradeoff to either choice. The tradeoff is some startup perf if you compile code
// that references this type, vs. a bit of a hit every time you use one of these methods
// because we must verify that the .cctor ran. For now, we'll make this class slower
// to use, but you can write code with quirks in it that only triggers iff you need legacy
// behavior (ie, if you need to not throw an exception, see if you need to throw it first
// via normal logic then check the compatibility flag).
// Initialize the s_map field right before it's going to be used, not the moment we
// JITs code that contains a call to this class. For this reason, explicitly create a
// .cctor instead of letting the compiler generate one with different initialization
// semantics.
static BinaryCompatibility()
{
s_map = new BinaryCompatibilityMap();
}
// For parsing a target Framework moniker, from the FrameworkName class
private const char c_componentSeparator = ',';
private const char c_keyValueSeparator = '=';
private const char c_versionValuePrefix = 'v';
private const String c_versionKey = "Version";
private const String c_profileKey = "Profile";
/// <summary>
/// BinaryCompatibilityMap is basically a bitvector. There is a boolean field for each of the
/// properties in BinaryCompatibility
/// </summary>
private sealed class BinaryCompatibilityMap
{
// A bit for each property
internal bool TargetsAtLeast_Phone_V7_1;
internal bool TargetsAtLeast_Phone_V8_0;
internal bool TargetsAtLeast_Desktop_V4_5;
internal bool TargetsAtLeast_Desktop_V4_5_1;
internal bool TargetsAtLeast_Desktop_V4_5_2;
internal bool TargetsAtLeast_Desktop_V4_5_3;
internal bool TargetsAtLeast_Desktop_V4_5_4;
internal bool TargetsAtLeast_Desktop_V5_0;
internal bool TargetsAtLeast_Silverlight_V4;
internal bool TargetsAtLeast_Silverlight_V5;
internal bool TargetsAtLeast_Silverlight_V6;
internal BinaryCompatibilityMap()
{
AddQuirksForFramework(AppWasBuiltForFramework, AppWasBuiltForVersion);
}
// The purpose of this method is to capture information about integrations & behavioral compatibility
// between our multiple different release vehicles. IE, if a behavior shows up in Silverlight version 5,
// does it show up in the .NET Framework version 4.5 and Windows Phone 8?
// Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
private void AddQuirksForFramework(TargetFrameworkId builtAgainstFramework, int buildAgainstVersion)
{
Contract.Requires(buildAgainstVersion > 0 || builtAgainstFramework == TargetFrameworkId.Unspecified);
switch (builtAgainstFramework)
{
case TargetFrameworkId.NetFramework:
case TargetFrameworkId.NetCore: // Treat Windows 8 tailored apps as normal desktop apps - same product
if (buildAgainstVersion >= 50000)
TargetsAtLeast_Desktop_V5_0 = true;
// Potential 4.5 servicing releases
if (buildAgainstVersion >= 40504)
TargetsAtLeast_Desktop_V4_5_4 = true;
if (buildAgainstVersion >= 40503)
TargetsAtLeast_Desktop_V4_5_3 = true;
if (buildAgainstVersion >= 40502)
TargetsAtLeast_Desktop_V4_5_2 = true;
if (buildAgainstVersion >= 40501)
TargetsAtLeast_Desktop_V4_5_1 = true;
if (buildAgainstVersion >= 40500)
{
TargetsAtLeast_Desktop_V4_5 = true;
// On XX/XX/XX we integrated all changes from the phone V7_1 into the branch from which contains Desktop V4_5, thus
// Any application built for V4_5 (or above) should have all the quirks for Phone V7_1 turned on.
AddQuirksForFramework(TargetFrameworkId.Phone, 70100);
// All Silverlight 5 behavior should be in the .NET Framework version 4.5
AddQuirksForFramework(TargetFrameworkId.Silverlight, 50000);
}
break;
case TargetFrameworkId.Phone:
if (buildAgainstVersion >= 80000)
{
TargetsAtLeast_Phone_V8_0 = true;
// @
}
if (buildAgainstVersion >= 710)
TargetsAtLeast_Phone_V7_1 = true;
break;
case TargetFrameworkId.Silverlight:
if (buildAgainstVersion >= 40000)
TargetsAtLeast_Silverlight_V4 = true;
if (buildAgainstVersion >= 50000)
TargetsAtLeast_Silverlight_V5 = true;
if (buildAgainstVersion >= 60000)
{
TargetsAtLeast_Silverlight_V6 = true;
// @
}
break;
case TargetFrameworkId.Unspecified:
break;
case TargetFrameworkId.NotYetChecked:
case TargetFrameworkId.Unrecognized:
Contract.Assert(false, "Bad framework kind");
break;
default:
Contract.Assert(false, "Error: we introduced a new Target Framework but did not update our binary compatibility map");
break;
}
}
}
#region String Parsing
// If this doesn't work, perhaps we could fall back to parsing the metadata version number.
private static bool ParseTargetFrameworkMonikerIntoEnum(String targetFrameworkMoniker, out TargetFrameworkId targetFramework, out int targetFrameworkVersion)
{
Contract.Requires(!String.IsNullOrEmpty(targetFrameworkMoniker));
targetFramework = TargetFrameworkId.NotYetChecked;
targetFrameworkVersion = 0;
String identifier = null;
String profile = null;
ParseFrameworkName(targetFrameworkMoniker, out identifier, out targetFrameworkVersion, out profile);
switch (identifier)
{
case ".NETFramework":
targetFramework = TargetFrameworkId.NetFramework;
break;
case ".NETPortable":
targetFramework = TargetFrameworkId.Portable;
break;
case ".NETCore":
targetFramework = TargetFrameworkId.NetCore;
break;
case "Silverlight":
targetFramework = TargetFrameworkId.Silverlight;
// Windows Phone 7 is Silverlight,Version=v4.0,Profile=WindowsPhone
// Windows Phone 7.1 is Silverlight,Version=v4.0,Profile=WindowsPhone71
if (!String.IsNullOrEmpty(profile))
{
if (profile == "WindowsPhone")
{
targetFramework = TargetFrameworkId.Phone;
targetFrameworkVersion = 70000;
}
else if (profile == "WindowsPhone71")
{
targetFramework = TargetFrameworkId.Phone;
targetFrameworkVersion = 70100;
}
else if (profile == "WindowsPhone8") // @
{
targetFramework = TargetFrameworkId.Phone;
targetFrameworkVersion = 80000;
}
else if (profile.StartsWith("WindowsPhone", StringComparison.Ordinal))
{
Contract.Assert(false, "This is a phone app, but we can't tell what version this is!");
targetFramework = TargetFrameworkId.Unrecognized;
targetFrameworkVersion = 70100;
}
else
{
Contract.Assert(false, String.Format(CultureInfo.InvariantCulture, "Unrecognized Silverlight profile \"{0}\". What is this, an XBox app?", profile));
targetFramework = TargetFrameworkId.Unrecognized;
}
}
break;
default:
Contract.Assert(false, String.Format(CultureInfo.InvariantCulture, "Unrecognized Target Framework Moniker in our Binary Compatibility class. Framework name: \"{0}\"", targetFrameworkMoniker));
targetFramework = TargetFrameworkId.Unrecognized;
break;
}
return true;
}
// This code was a constructor copied from the FrameworkName class, which is located in System.dll.
// Parses strings in the following format: "<identifier>, Version=[v|V]<version>, Profile=<profile>"
// - The identifier and version is required, profile is optional
// - Only three components are allowed.
// - The version string must be in the System.Version format; an optional "v" or "V" prefix is allowed
private static void ParseFrameworkName(String frameworkName, out String identifier, out int version, out String profile)
{
if (frameworkName == null)
{
throw new ArgumentNullException("frameworkName");
}
if (frameworkName.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_StringZeroLength"), "frameworkName");
}
Contract.EndContractBlock();
String[] components = frameworkName.Split(c_componentSeparator);
version = 0;
// Identifer and Version are required, Profile is optional.
if (components.Length < 2 || components.Length > 3)
{
throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameTooShort"), "frameworkName");
}
//
// 1) Parse the "Identifier", which must come first. Trim any whitespace
//
identifier = components[0].Trim();
if (identifier.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameInvalid"), "frameworkName");
}
bool versionFound = false;
profile = null;
//
// The required "Version" and optional "Profile" component can be in any order
//
for (int i = 1; i < components.Length; i++)
{
// Get the key/value pair separated by '='
string[] keyValuePair = components[i].Split(c_keyValueSeparator);
if (keyValuePair.Length != 2)
{
throw new ArgumentException(Environment.GetResourceString("SR.Argument_FrameworkNameInvalid"), "frameworkName");
}
// Get the key and value, trimming any whitespace
string key = keyValuePair[0].Trim();
string value = keyValuePair[1].Trim();
//
// 2) Parse the required "Version" key value
//
if (key.Equals(c_versionKey, StringComparison.OrdinalIgnoreCase))
{
versionFound = true;
// Allow the version to include a 'v' or 'V' prefix...
if (value.Length > 0 && (value[0] == c_versionValuePrefix || value[0] == 'V'))
{
value = value.Substring(1);
}
Version realVersion = new Version(value);
// The version class will represent some unset values as -1 internally (instead of 0).
version = realVersion.Major * 10000;
if (realVersion.Minor > 0)
version += realVersion.Minor * 100;
if (realVersion.Build > 0)
version += realVersion.Build;
}
//
// 3) Parse the optional "Profile" key value
//
else if (key.Equals(c_profileKey, StringComparison.OrdinalIgnoreCase))
{
if (!String.IsNullOrEmpty(value))
{
profile = value;
}
}
else
{
throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameInvalid"), "frameworkName");
}
}
if (!versionFound)
{
throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameMissingVersion"), "frameworkName");
}
}
private static void ReadTargetFrameworkId()
{
String targetFrameworkName = AppDomain.CurrentDomain.GetTargetFrameworkName();
// Write to a local then to _targetFramework, after writing the version number.
TargetFrameworkId fxId;
int fxVersion = 0;
if (targetFrameworkName == null)
fxId = TargetFrameworkId.Unspecified;
else if (!ParseTargetFrameworkMonikerIntoEnum(targetFrameworkName, out fxId, out fxVersion))
fxId = TargetFrameworkId.Unrecognized;
s_AppWasBuiltForFramework = fxId;
s_AppWasBuiltForVersion = fxVersion;
}
#endregion String Parsing
#endregion private
}
}

View File

@@ -0,0 +1,46 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: ComponentGuaranteesAttribute
**
**
** Purpose: Tracking whether a component signs up for a
** a strong contract spanning multiple versions.
**
===========================================================*/
using System;
namespace System.Runtime.Versioning {
[Flags]
[Serializable]
public enum ComponentGuaranteesOptions
{
None = 0,
Exchange = 0x1,
Stable = 0x2,
SideBySide = 0x4,
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class |
AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate |
AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property |
AttributeTargets.Constructor | AttributeTargets.Event,
AllowMultiple = false, Inherited = false)]
public sealed class ComponentGuaranteesAttribute : Attribute {
private ComponentGuaranteesOptions _guarantees;
public ComponentGuaranteesAttribute(ComponentGuaranteesOptions guarantees)
{
_guarantees = guarantees;
}
public ComponentGuaranteesOptions Guarantees {
get { return _guarantees; }
}
}
}

View File

@@ -0,0 +1,81 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: MultitargetingHelpers
**
** <OWNER>[....]</OWNER>
**
**
** Purpose: Central repository for helpers supporting
** multitargeting, such as emitting the correct version numbers
** and assembly names.
**
**
===========================================================*/
namespace System.Runtime.Versioning
{
using System;
using System.IO;
using System.Text;
using System.Diagnostics.Contracts;
internal static class MultitargetingHelpers
{
// default type converter
private static Func<Type, String> defaultConverter = (t) => t.AssemblyQualifiedName;
// This method gets assembly info for the corresponding type. If the typeConverter
// is provided it is used to get this information.
internal static string GetAssemblyQualifiedName(Type type, Func<Type, String> converter)
{
string assemblyFullName = null;
if (type != null)
{
if (converter != null)
{
try
{
assemblyFullName = converter(type);
//
}
catch (Exception e)
{
if (IsSecurityOrCriticalException(e))
{
throw;
}
}
}
if (assemblyFullName == null)
{
assemblyFullName = defaultConverter(type);
}
}
return assemblyFullName;
}
private static bool IsCriticalException(Exception ex)
{
return ex is NullReferenceException
|| ex is StackOverflowException
|| ex is OutOfMemoryException
|| ex is System.Threading.ThreadAbortException
|| ex is IndexOutOfRangeException
|| ex is AccessViolationException;
}
private static bool IsSecurityOrCriticalException(Exception ex)
{
return (ex is System.Security.SecurityException) || IsCriticalException(ex);
}
}
}

View File

@@ -0,0 +1,241 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Purpose: Resource annotation rules.
**
===========================================================*/
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Win32;
using System.Diagnostics.Contracts;
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
[Conditional("RESOURCE_ANNOTATION_WORK")]
public sealed class ResourceConsumptionAttribute : Attribute
{
private ResourceScope _consumptionScope;
private ResourceScope _resourceScope;
public ResourceConsumptionAttribute(ResourceScope resourceScope)
{
_resourceScope = resourceScope;
_consumptionScope = _resourceScope;
}
public ResourceConsumptionAttribute(ResourceScope resourceScope, ResourceScope consumptionScope)
{
_resourceScope = resourceScope;
_consumptionScope = consumptionScope;
}
public ResourceScope ResourceScope {
get { return _resourceScope; }
}
public ResourceScope ConsumptionScope {
get { return _consumptionScope; }
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
[Conditional("RESOURCE_ANNOTATION_WORK")]
public sealed class ResourceExposureAttribute : Attribute
{
private ResourceScope _resourceExposureLevel;
public ResourceExposureAttribute(ResourceScope exposureLevel)
{
_resourceExposureLevel = exposureLevel;
}
public ResourceScope ResourceExposureLevel {
get { return _resourceExposureLevel; }
}
}
// Default visibility is Public, which isn't specified in this enum.
// Public == the lack of Private or Assembly
// Does this actually work? Need to investigate that.
[Flags]
public enum ResourceScope
{
None = 0,
// Resource type
Machine = 0x1,
Process = 0x2,
AppDomain = 0x4,
Library = 0x8,
// Visibility
Private = 0x10, // Private to this one class.
Assembly = 0x20, // Assembly-level, like C#'s "internal"
}
[Flags]
internal enum SxSRequirements
{
None = 0,
AppDomainID = 0x1,
ProcessID = 0x2,
CLRInstanceID = 0x4, // for multiple CLR's within the process
AssemblyName = 0x8,
TypeName = 0x10
}
public static class VersioningHelper
{
// These depend on the exact values given to members of the ResourceScope enum.
private const ResourceScope ResTypeMask = ResourceScope.Machine | ResourceScope.Process | ResourceScope.AppDomain | ResourceScope.Library;
private const ResourceScope VisibilityMask = ResourceScope.Private | ResourceScope.Assembly;
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.Process)]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int GetRuntimeId();
public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to)
{
return MakeVersionSafeName(name, from, to, null);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to, Type type)
{
ResourceScope fromResType = from & ResTypeMask;
ResourceScope toResType = to & ResTypeMask;
if (fromResType > toResType)
throw new ArgumentException(Environment.GetResourceString("Argument_ResourceScopeWrongDirection", fromResType, toResType), "from");
SxSRequirements requires = GetRequirements(to, from);
if ((requires & (SxSRequirements.AssemblyName | SxSRequirements.TypeName)) != 0 && type == null)
throw new ArgumentNullException("type", Environment.GetResourceString("ArgumentNull_TypeRequiredByResourceScope"));
// Add in process ID, CLR base address, and appdomain ID's. Also, use a character identifier
// to ensure that these can never accidentally overlap (ie, you create enough appdomains and your
// appdomain ID might equal your process ID).
StringBuilder safeName = new StringBuilder(name);
char separator = '_';
if ((requires & SxSRequirements.ProcessID) != 0) {
safeName.Append(separator);
safeName.Append('p');
safeName.Append(Win32Native.GetCurrentProcessId());
}
if ((requires & SxSRequirements.CLRInstanceID) != 0) {
String clrID = GetCLRInstanceString();
safeName.Append(separator);
safeName.Append('r');
safeName.Append(clrID);
}
if ((requires & SxSRequirements.AppDomainID) != 0) {
safeName.Append(separator);
safeName.Append("ad");
safeName.Append(AppDomain.CurrentDomain.Id);
}
if ((requires & SxSRequirements.TypeName) != 0) {
safeName.Append(separator);
safeName.Append(type.Name);
}
if ((requires & SxSRequirements.AssemblyName) != 0) {
safeName.Append(separator);
safeName.Append(type.Assembly.FullName);
}
return safeName.ToString();
}
private static String GetCLRInstanceString()
{
int id = GetRuntimeId();
return id.ToString(CultureInfo.InvariantCulture);
}
private static SxSRequirements GetRequirements(ResourceScope consumeAsScope, ResourceScope calleeScope)
{
SxSRequirements requires = SxSRequirements.None;
switch(calleeScope & ResTypeMask) {
case ResourceScope.Machine:
switch(consumeAsScope & ResTypeMask) {
case ResourceScope.Machine:
// No work
break;
case ResourceScope.Process:
requires |= SxSRequirements.ProcessID;
break;
case ResourceScope.AppDomain:
requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID | SxSRequirements.ProcessID;
break;
default:
throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", consumeAsScope), "consumeAsScope");
}
break;
case ResourceScope.Process:
if ((consumeAsScope & ResourceScope.AppDomain) != 0)
requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID;
break;
case ResourceScope.AppDomain:
// No work
break;
default:
throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", calleeScope), "calleeScope");
}
switch(calleeScope & VisibilityMask) {
case ResourceScope.None: // Public - implied
switch(consumeAsScope & VisibilityMask) {
case ResourceScope.None: // Public - implied
// No work
break;
case ResourceScope.Assembly:
requires |= SxSRequirements.AssemblyName;
break;
case ResourceScope.Private:
requires |= SxSRequirements.TypeName | SxSRequirements.AssemblyName;
break;
default:
throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", consumeAsScope), "consumeAsScope");
}
break;
case ResourceScope.Assembly:
if ((consumeAsScope & ResourceScope.Private) != 0)
requires |= SxSRequirements.TypeName;
break;
case ResourceScope.Private:
// No work
break;
default:
throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", calleeScope), "calleeScope");
}
if (consumeAsScope == calleeScope) {
Contract.Assert(requires == SxSRequirements.None, "Computed a strange set of required resource scoping. It's probably wrong.");
}
return requires;
}
}
}

View File

@@ -0,0 +1,47 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//
/*============================================================
**
** Class: TargetFrameworkAttribute
**
**
** Purpose: Identifies which SKU and version of the .NET
** Framework that a particular library was compiled against.
** Emitted by VS, and can help catch deployment problems.
**
===========================================================*/
using System;
using System.Diagnostics.Contracts;
namespace System.Runtime.Versioning {
[AttributeUsageAttribute(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
public sealed class TargetFrameworkAttribute : Attribute {
private String _frameworkName; // A target framework moniker
private String _frameworkDisplayName;
// The frameworkName parameter is intended to be the string form of a FrameworkName instance.
public TargetFrameworkAttribute(String frameworkName)
{
if (frameworkName == null)
throw new ArgumentNullException("frameworkName");
Contract.EndContractBlock();
_frameworkName = frameworkName;
}
// The target framework moniker that this assembly was compiled against.
// Use the FrameworkName class to interpret target framework monikers.
public String FrameworkName {
get { return _frameworkName; }
}
public String FrameworkDisplayName {
get { return _frameworkDisplayName; }
set { _frameworkDisplayName = value; }
}
}
}

View File

@@ -0,0 +1,29 @@
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Purpose: Describe the target framework of the application or AppDomain.
**
===========================================================*/
using System;
using System.Runtime.CompilerServices;
namespace System.Runtime.Versioning
{
// What type of .NET Framework was this application compiled against?
[FriendAccessAllowed]
internal enum TargetFrameworkId
{
NotYetChecked = 0,
Unrecognized = 1, // Unknown type, such as a new SKU (like watches or cars)
Unspecified = 2, // The TargetFrameworkAttribute was created in v4.0. And apps compiled outside VS will not have this attribute.
NetFramework = 3, // Desktop - Client or Server or ServerCore.
Portable = 4, // Portable Library v1 Note: We do not expect people to build executables against portable libraries!
NetCore = 5, // .NET Core = Windows 8 Immersive and Portable Library v2+
Silverlight = 6, // Silverlight but not the Phone
Phone = 7, // Windows Phone 7 or higher
}
}