Import System.Diagnostics.Process
[mono-project.git] / mcs / class / referencesource / mscorlib / system / runtime / versioning / resourceattributes.cs
blob184836c5be6534d426b6b2acbf0b0349409c8e4d
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
6 /*============================================================
7 **
8 ** Purpose: Resource annotation rules.
9 **
10 ===========================================================*/
11 using System;
12 using System.Diagnostics;
13 using System.Globalization;
14 using System.Runtime.CompilerServices;
15 using System.Text;
16 using Microsoft.Win32;
17 using System.Diagnostics.Contracts;
19 namespace System.Runtime.Versioning
21 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
22 [Conditional("RESOURCE_ANNOTATION_WORK")]
23 public sealed class ResourceConsumptionAttribute : Attribute
25 private ResourceScope _consumptionScope;
26 private ResourceScope _resourceScope;
28 public ResourceConsumptionAttribute(ResourceScope resourceScope)
30 _resourceScope = resourceScope;
31 _consumptionScope = _resourceScope;
34 public ResourceConsumptionAttribute(ResourceScope resourceScope, ResourceScope consumptionScope)
36 _resourceScope = resourceScope;
37 _consumptionScope = consumptionScope;
40 public ResourceScope ResourceScope {
41 get { return _resourceScope; }
44 public ResourceScope ConsumptionScope {
45 get { return _consumptionScope; }
49 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
50 [Conditional("RESOURCE_ANNOTATION_WORK")]
51 public sealed class ResourceExposureAttribute : Attribute
53 private ResourceScope _resourceExposureLevel;
55 public ResourceExposureAttribute(ResourceScope exposureLevel)
57 _resourceExposureLevel = exposureLevel;
60 public ResourceScope ResourceExposureLevel {
61 get { return _resourceExposureLevel; }
66 // Default visibility is Public, which isn't specified in this enum.
67 // Public == the lack of Private or Assembly
68 // Does this actually work? Need to investigate that.
69 [Flags]
70 public enum ResourceScope
72 None = 0,
73 // Resource type
74 Machine = 0x1,
75 Process = 0x2,
76 AppDomain = 0x4,
77 Library = 0x8,
78 // Visibility
79 Private = 0x10, // Private to this one class.
80 Assembly = 0x20, // Assembly-level, like C#'s "internal"
84 [Flags]
85 internal enum SxSRequirements
87 None = 0,
88 AppDomainID = 0x1,
89 ProcessID = 0x2,
90 CLRInstanceID = 0x4, // for multiple CLR's within the process
91 AssemblyName = 0x8,
92 TypeName = 0x10
95 public static class VersioningHelper
97 // These depend on the exact values given to members of the ResourceScope enum.
98 private const ResourceScope ResTypeMask = ResourceScope.Machine | ResourceScope.Process | ResourceScope.AppDomain | ResourceScope.Library;
99 private const ResourceScope VisibilityMask = ResourceScope.Private | ResourceScope.Assembly;
101 [System.Security.SecuritySafeCritical]
102 [ResourceExposure(ResourceScope.Process)]
103 [MethodImpl(MethodImplOptions.InternalCall)]
104 private static extern int GetRuntimeId();
106 public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to)
108 return MakeVersionSafeName(name, from, to, null);
111 [System.Security.SecuritySafeCritical] // auto-generated
112 [ResourceExposure(ResourceScope.None)]
113 [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
114 public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to, Type type)
116 ResourceScope fromResType = from & ResTypeMask;
117 ResourceScope toResType = to & ResTypeMask;
118 if (fromResType > toResType)
119 throw new ArgumentException(Environment.GetResourceString("Argument_ResourceScopeWrongDirection", fromResType, toResType), "from");
121 SxSRequirements requires = GetRequirements(to, from);
123 if ((requires & (SxSRequirements.AssemblyName | SxSRequirements.TypeName)) != 0 && type == null)
124 throw new ArgumentNullException("type", Environment.GetResourceString("ArgumentNull_TypeRequiredByResourceScope"));
126 // Add in process ID, CLR base address, and appdomain ID's. Also, use a character identifier
127 // to ensure that these can never accidentally overlap (ie, you create enough appdomains and your
128 // appdomain ID might equal your process ID).
129 StringBuilder safeName = new StringBuilder(name);
130 char separator = '_';
131 if ((requires & SxSRequirements.ProcessID) != 0) {
132 safeName.Append(separator);
133 safeName.Append('p');
134 #if MONO
135 safeName.Append (NativeMethods.GetCurrentProcessId ());
136 #else
137 safeName.Append(Win32Native.GetCurrentProcessId());
138 #endif
140 if ((requires & SxSRequirements.CLRInstanceID) != 0) {
141 String clrID = GetCLRInstanceString();
142 safeName.Append(separator);
143 safeName.Append('r');
144 safeName.Append(clrID);
146 if ((requires & SxSRequirements.AppDomainID) != 0) {
147 safeName.Append(separator);
148 safeName.Append("ad");
149 safeName.Append(AppDomain.CurrentDomain.Id);
151 if ((requires & SxSRequirements.TypeName) != 0) {
152 safeName.Append(separator);
153 safeName.Append(type.Name);
155 if ((requires & SxSRequirements.AssemblyName) != 0) {
156 safeName.Append(separator);
157 safeName.Append(type.Assembly.FullName);
159 return safeName.ToString();
162 private static String GetCLRInstanceString()
164 int id = GetRuntimeId();
165 return id.ToString(CultureInfo.InvariantCulture);
168 private static SxSRequirements GetRequirements(ResourceScope consumeAsScope, ResourceScope calleeScope)
170 SxSRequirements requires = SxSRequirements.None;
172 switch(calleeScope & ResTypeMask) {
173 case ResourceScope.Machine:
174 switch(consumeAsScope & ResTypeMask) {
175 case ResourceScope.Machine:
176 // No work
177 break;
179 case ResourceScope.Process:
180 requires |= SxSRequirements.ProcessID;
181 break;
183 case ResourceScope.AppDomain:
184 requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID | SxSRequirements.ProcessID;
185 break;
187 default:
188 throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", consumeAsScope), "consumeAsScope");
190 break;
192 case ResourceScope.Process:
193 if ((consumeAsScope & ResourceScope.AppDomain) != 0)
194 requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID;
195 break;
197 case ResourceScope.AppDomain:
198 // No work
199 break;
201 default:
202 throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", calleeScope), "calleeScope");
205 switch(calleeScope & VisibilityMask) {
206 case ResourceScope.None: // Public - implied
207 switch(consumeAsScope & VisibilityMask) {
208 case ResourceScope.None: // Public - implied
209 // No work
210 break;
212 case ResourceScope.Assembly:
213 requires |= SxSRequirements.AssemblyName;
214 break;
216 case ResourceScope.Private:
217 requires |= SxSRequirements.TypeName | SxSRequirements.AssemblyName;
218 break;
220 default:
221 throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", consumeAsScope), "consumeAsScope");
223 break;
225 case ResourceScope.Assembly:
226 if ((consumeAsScope & ResourceScope.Private) != 0)
227 requires |= SxSRequirements.TypeName;
228 break;
230 case ResourceScope.Private:
231 // No work
232 break;
234 default:
235 throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", calleeScope), "calleeScope");
238 if (consumeAsScope == calleeScope) {
239 Contract.Assert(requires == SxSRequirements.None, "Computed a strange set of required resource scoping. It's probably wrong.");
242 return requires;