Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / Microsoft / Internal / ReflectionInvoke.cs
1 #if !SILVERLIGHT && CLR40\r
2 \r
3 using System;\r
4 using System.Reflection;\r
5 using System.Security;\r
6 using System.Security.Permissions;\r
7 \r
8 namespace Microsoft.Internal\r
9 {\r
10     internal static class ReflectionInvoke\r
11     {\r
12         private static readonly ReflectionPermission _memberAccess = new ReflectionPermission(ReflectionPermissionFlag.MemberAccess);\r
13         private static readonly ReflectionPermission _restrictedMemberAccess = new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess);\r
14 \r
15         public static object SafeCreateInstance(this Type type, params object[] arguments)\r
16         {\r
17             DemandMemberAccessIfNeeded(type);\r
18 \r
19             return Activator.CreateInstance(type, arguments);\r
20         }\r
21 \r
22         public static object SafeInvoke(this ConstructorInfo constructor, params object[] arguments)\r
23         {\r
24             DemandMemberAccessIfNeeded(constructor);\r
25 \r
26             return constructor.Invoke(arguments);\r
27         }\r
28 \r
29         public static object SafeInvoke(this MethodInfo method, object instance, params object[] arguments)\r
30         {\r
31             DemandMemberAccessIfNeeded(method);\r
32 \r
33             return method.Invoke(instance, arguments);\r
34         }\r
35 \r
36         public static object SafeGetValue(this FieldInfo field, object instance)\r
37         {\r
38             DemandMemberAccessIfNeeded(field);\r
39 \r
40             return field.GetValue(instance);\r
41         }\r
42 \r
43         public static void SafeSetValue(this FieldInfo field, object instance, object value)\r
44         {\r
45             DemandMemberAccessIfNeeded(field);\r
46 \r
47             field.SetValue(instance, value);\r
48         }\r
49 \r
50         public static void DemandMemberAccessIfNeeded(MethodInfo method)\r
51         {\r
52             if (!method.IsVisible())\r
53             {\r
54                 DemandMemberAccess(method);\r
55             }\r
56         }\r
57 \r
58         private static void DemandMemberAccessIfNeeded(FieldInfo field)\r
59         {\r
60             if (!field.IsVisible())\r
61             {\r
62                 DemandMemberAccess(field);\r
63             }\r
64         }\r
65 \r
66         public static void DemandMemberAccessIfNeeded(Type type)\r
67         {\r
68             // Consult UnderlyingSystemType this is the type that Activator.CreateInstance creates            \r
69             if (!type.UnderlyingSystemType.IsVisible)\r
70             {\r
71                 DemandMemberAccess(type);\r
72             }\r
73         }\r
74 \r
75         private static void DemandMemberAccessIfNeeded(ConstructorInfo constructor)\r
76         {\r
77             if (!constructor.IsVisible())\r
78             {\r
79                 DemandMemberAccess(constructor);\r
80             }\r
81         }\r
82 \r
83         private static void DemandMemberAccess(MemberInfo target)\r
84         {\r
85             try\r
86             {\r
87                 _memberAccess.Demand();\r
88             }\r
89             catch (SecurityException)\r
90             {   // The caller doesn't have member access, but let's see whether they have access to\r
91                 // members of assemblies with less or equal permissions (this mimics Reflection's behavior)\r
92 \r
93                 DemandRestrictedMemberAccess(target);\r
94             }\r
95         }\r
96 \r
97         private static void DemandRestrictedMemberAccess(MemberInfo target)\r
98         {\r
99             Assembly targetAssembly = target.Assembly();\r
100 \r
101             PermissionSet targetGrantSet = UnsafePermissionSet(targetAssembly);\r
102             targetGrantSet.AddPermission(_restrictedMemberAccess);\r
103             targetGrantSet.Demand();\r
104         }\r
105 \r
106         [SecuritySafeCritical] // PermissionSet is [SecurityCritical]\r
107         private static PermissionSet UnsafePermissionSet(Assembly assembly)\r
108         {\r
109             return assembly.PermissionSet;\r
110         }\r
111     }\r
112 }\r
113 \r
114 #endif