Added support for adding "new-style" declarative security (i.e. .NET 2.0 compatible).

This commit is contained in:
jfrijters 2009-11-09 06:38:30 +00:00
Родитель 5e56f47c94
Коммит 3ea4d4aa8f
7 изменённых файлов: 150 добавлений и 0 удалений

Просмотреть файл

@ -52,6 +52,7 @@ namespace IKVM.Reflection.Emit
private List<ResourceFile> resourceFiles = new List<ResourceFile>();
private List<ModuleBuilder> modules = new List<ModuleBuilder>();
private List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
private List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
private struct ResourceFile
{
@ -128,6 +129,11 @@ namespace IKVM.Reflection.Emit
}
}
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
{
declarativeSecurity.Add(customBuilder);
}
public void SetEntryPoint(MethodBuilder mb)
{
SetEntryPoint(mb, PEFileKinds.ConsoleApplication);
@ -221,6 +227,8 @@ namespace IKVM.Reflection.Emit
manifestModule.SetAssemblyCustomAttribute(cab);
}
manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);
foreach (ResourceFile resfile in resourceFiles)
{
int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);

Просмотреть файл

@ -56,6 +56,11 @@ namespace IKVM.Reflection.Emit
methodBuilder.SetCustomAttribute(customBuilder);
}
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
{
methodBuilder.__AddDeclarativeSecurity(customBuilder);
}
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
{
methodBuilder.AddDeclarativeSecurity(securityAction, permissionSet);

Просмотреть файл

@ -121,6 +121,37 @@ namespace IKVM.Reflection.Emit
return str.ToArray();
}
internal void WriteNamedArgForDeclSecurity(ByteBuffer bb)
{
// NumNamed
int named = 0;
if (cab.namedFields != null)
{
named += cab.namedFields.Length;
}
if (cab.namedProperties != null)
{
named += cab.namedProperties.Length;
}
WritePackedLen(named);
if (cab.namedFields != null)
{
for (int i = 0; i < cab.namedFields.Length; i++)
{
WriteNamedArg(0x53, cab.namedFields[i].FieldType, cab.namedFields[i].Name, cab.fieldValues[i]);
}
}
if (cab.namedProperties != null)
{
for (int i = 0; i < cab.namedProperties.Length; i++)
{
WriteNamedArg(0x54, cab.namedProperties[i].PropertyType, cab.namedProperties[i].Name, cab.propertyValues[i]);
}
}
str.Position = 0;
bb.Write(str);
}
private void WriteNamedArg(byte fieldOrProperty, Type type, string name, object value)
{
str.WriteByte(fieldOrProperty);
@ -459,6 +490,11 @@ namespace IKVM.Reflection.Emit
return constructorArgs[pos];
}
internal int ConstructorArgumentCount
{
get { return constructorArgs == null ? 0 : constructorArgs.Length; }
}
internal object GetFieldValue(string name)
{
if (namedFields != null)
@ -473,5 +509,11 @@ namespace IKVM.Reflection.Emit
}
return null;
}
internal void WriteNamedArgumentsForDeclSecurity(ModuleBuilder moduleBuilder, ByteBuffer bb)
{
BlobWriter bw = new BlobWriter(moduleBuilder, this);
bw.WriteNamedArgForDeclSecurity(bb);
}
}
}

Просмотреть файл

@ -51,6 +51,7 @@ namespace IKVM.Reflection.Emit
private readonly CallingConventions callingConvention;
private List<ParameterBuilder> parameters;
private GenericTypeParameterBuilder[] gtpb;
private List<CustomAttributeBuilder> declarativeSecurity;
internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention)
{
@ -282,6 +283,16 @@ namespace IKVM.Reflection.Emit
}
}
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
{
attributes |= MethodAttributes.HasSecurity;
if (declarativeSecurity == null)
{
declarativeSecurity = new List<CustomAttributeBuilder>();
}
declarativeSecurity.Add(customBuilder);
}
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
{
this.ModuleBuilder.AddDeclaritiveSecurity(pseudoToken, securityAction, permissionSet);
@ -508,6 +519,11 @@ namespace IKVM.Reflection.Emit
{
rva = -1;
}
if (declarativeSecurity != null)
{
this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity);
}
}
internal ModuleBuilder ModuleBuilder

Просмотреть файл

@ -332,6 +332,56 @@ namespace IKVM.Reflection.Emit
this.Tables.DeclSecurity.AddRecord(rec);
}
internal void AddDeclarativeSecurity(int token, List<CustomAttributeBuilder> declarativeSecurity)
{
Dictionary<int, List<CustomAttributeBuilder>> ordered = new Dictionary<int, List<CustomAttributeBuilder>>();
foreach (CustomAttributeBuilder cab in declarativeSecurity)
{
int action;
// check for HostProtectionAttribute without SecurityAction
if (cab.ConstructorArgumentCount == 0)
{
action = (int)System.Security.Permissions.SecurityAction.LinkDemand;
}
else
{
action = (int)cab.GetConstructorArgument(0);
}
List<CustomAttributeBuilder> list;
if (!ordered.TryGetValue(action, out list))
{
list = new List<CustomAttributeBuilder>();
ordered.Add(action, list);
}
list.Add(cab);
}
foreach (KeyValuePair<int, List<CustomAttributeBuilder>> kv in ordered)
{
TableHeap.DeclSecurityTable.Record rec = new TableHeap.DeclSecurityTable.Record();
rec.Action = (short)kv.Key;
rec.Parent = token;
rec.PermissionSet = WriteDeclSecurityBlob(kv.Value);
this.Tables.DeclSecurity.AddRecord(rec);
}
}
private int WriteDeclSecurityBlob(List<CustomAttributeBuilder> list)
{
ByteBuffer namedArgs = new ByteBuffer(100);
ByteBuffer bb = new ByteBuffer(list.Count * 100);
bb.Write((byte)'.');
bb.WriteCompressedInt(list.Count);
foreach (CustomAttributeBuilder cab in list)
{
bb.Write(cab.Constructor.DeclaringType.AssemblyQualifiedName);
namedArgs.Clear();
cab.WriteNamedArgumentsForDeclSecurity(this, namedArgs);
bb.WriteCompressedInt(namedArgs.Length);
bb.Write(namedArgs);
}
return this.Blobs.Add(bb);
}
public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute)
{
TableHeap.ManifestResourceTable.Record rec = new TableHeap.ManifestResourceTable.Record();

Просмотреть файл

@ -184,6 +184,7 @@ namespace IKVM.Reflection.Emit
private TypeAttributes attribs;
private TypeFlags typeFlags;
private GenericTypeParameterBuilder[] gtpb;
private List<CustomAttributeBuilder> declarativeSecurity;
[Flags]
private enum TypeFlags
@ -453,6 +454,16 @@ namespace IKVM.Reflection.Emit
}
}
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
{
attribs |= TypeAttributes.HasSecurity;
if (declarativeSecurity == null)
{
declarativeSecurity = new List<CustomAttributeBuilder>();
}
declarativeSecurity.Add(customBuilder);
}
public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
{
this.ModuleBuilder.AddDeclaritiveSecurity(token, securityAction, permissionSet);
@ -515,6 +526,10 @@ namespace IKVM.Reflection.Emit
}
events = null;
}
if (declarativeSecurity != null)
{
this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity);
}
return new BakedType(this);
}

Просмотреть файл

@ -160,6 +160,20 @@ namespace IKVM.Reflection.Emit.Writer
Write(BitConverter.DoubleToInt64Bits(value));
}
internal void Write(string str)
{
if (str == null)
{
Write((byte)0xFF);
}
else
{
byte[] buf = Encoding.UTF8.GetBytes(str);
WriteCompressedInt(buf.Length);
Write(buf);
}
}
internal void WriteCompressedInt(int value)
{
if (value <= 0x7F)