// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // Missing XML comment for publicly visible type or member #pragma warning disable 1591 using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Debugger.Interop.MetaData; using Debugger.Interop.CorDebug; using Debugger.Interop.CorSym; namespace Debugger.Interop.MetaData { /// Wrapper for the unmanaged metadata API. /// http://msdn.microsoft.com/en-us/library/ms230172.aspx public class MetaDataImport { const int DefaultBufferSize = 8; // If buffer is too small, enlarge it const int BufferSizeMultiplier = 4; IMetaDataImport metaData; public MetaDataImport(ICorDebugModule pModule) { Guid guid = new Guid("{ 0x7dac8207, 0xd3ae, 0x4c75, { 0x9b, 0x67, 0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44 } }"); metaData = (IMetaDataImport)pModule.GetMetaDataInterface(ref guid); TrackedComObjects.Track(metaData); } public ISymUnmanagedReader GetSymReader(string fullname, string searchPath) { try { ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); TrackedComObjects.Track(symBinder); return symBinder.GetReaderForFile(metaData, fullname, searchPath); } catch (COMException) { return null; } } public ISymUnmanagedReader GetSymReader(IStream stream) { try { ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); TrackedComObjects.Track(symBinder); return symBinder.GetReaderFromStream(metaData, stream); } catch (COMException) { return null; } } // CloseEnum, CountEnum and ResetEnum are not wrapped, use them directly // GetNameFromToken is obsolete public uint[] EnumCustomAttributes(uint token_Scope, uint token_TypeOfAttributes) { return EnumerateTokens(metaData.EnumCustomAttributes, token_Scope, token_TypeOfAttributes); } public IEnumerable EnumCustomAttributeProps(uint token_Scope, uint token_TypeOfAttributes) { foreach(uint token in EnumerateTokens(metaData.EnumCustomAttributes, token_Scope, token_TypeOfAttributes)) { yield return GetCustomAttributeProps(token); } } public uint[] EnumEvents(uint typeDef) { return EnumerateTokens(metaData.EnumEvents, typeDef); } public IEnumerable EnumEventProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumEvents, typeDef)) { yield return GetEventProps(token); } } public uint[] EnumFields(uint typeDef) { return EnumerateTokens(metaData.EnumFields, typeDef); } public IEnumerable EnumFieldProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumFields, typeDef)) { yield return GetFieldProps(token); } } public uint[] EnumFieldsWithName(uint typeDef, string name) { return EnumerateTokens(metaData.EnumFieldsWithName, typeDef, name); } public IEnumerable EnumFieldPropsWithName(uint typeDef, string name) { foreach(uint token in EnumerateTokens(metaData.EnumFieldsWithName, typeDef, name)) { yield return GetFieldProps(token); } } public uint[] EnumGenericParams(uint typeDef_methodDef) { return EnumerateTokens(metaData.EnumGenericParams, typeDef_methodDef); } /// MethodDef tokens public uint[] EnumInterfaceImpls(uint typeDef) { return EnumerateTokens(metaData.EnumInterfaceImpls, typeDef); } public IEnumerable EnumInterfaceImplProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumInterfaceImpls, typeDef)) { yield return GetInterfaceImplProps(token); } } public uint[] EnumMemberRefs(uint typeDef_typeRef_methodDef_moduleRef) { return EnumerateTokens(metaData.EnumMemberRefs, typeDef_typeRef_methodDef_moduleRef); } public IEnumerable EnumMemberRefProps(uint typeDef_typeRef_methodDef_moduleRef) { foreach(uint token in EnumerateTokens(metaData.EnumMemberRefs, typeDef_typeRef_methodDef_moduleRef)) { yield return GetMemberRefProps(token); } } public uint[] EnumMembers(uint typeDef) { return EnumerateTokens(metaData.EnumMembers, typeDef); } public IEnumerable EnumMemberProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumMembers, typeDef)) { yield return GetMemberProps(token); } } public uint[] EnumMembersWithName(uint typeDef, string name) { return EnumerateTokens(metaData.EnumMembersWithName, typeDef, name); } public IEnumerable EnumMemberPropsWithName(uint typeDef, string name) { foreach(uint token in EnumerateTokens(metaData.EnumMembersWithName, typeDef, name)) { yield return GetMemberProps(token); } } /// MethodBody and MethodDeclaration tokens public IEnumerable EnumMethodImpls(uint typeDef) { IntPtr enumerator = IntPtr.Zero; while(true) { MethodImpl ret = new MethodImpl(); uint[] body = new uint[1]; uint[] decl = new uint[1]; uint fetched; metaData.EnumMethodImpls(ref enumerator, typeDef, body, decl, 1, out fetched); if (fetched == 0) break; ret.MethodBody = body[0]; ret.MethodDecl = decl[0]; yield return ret; } metaData.CloseEnum(enumerator); } public uint[] EnumMethods(uint typeDef) { return EnumerateTokens(metaData.EnumMethods, typeDef); } public IEnumerable EnumMethodProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumMethods, typeDef)) { yield return GetMethodProps(token); } } /// Events or properties public uint[] EnumMethodSemantics(uint methodDef) { return EnumerateTokens(metaData.EnumMethodSemantics, methodDef); } public uint[] EnumMethodsWithName(uint typeDef, string name) { return EnumerateTokens(metaData.EnumMethodsWithName, typeDef, name); } public IEnumerable EnumMethodPropsWithName(uint typeDef, string name) { foreach(uint token in EnumerateTokens(metaData.EnumMethodsWithName, typeDef, name)) { yield return GetMethodProps(token); } } public uint[] EnumModuleRefs() { return EnumerateTokens(metaData.EnumModuleRefs); } public IEnumerable EnumModuleRefProps() { foreach(uint token in EnumerateTokens(metaData.EnumModuleRefs)) { yield return GetModuleRefProps(token); } } public uint[] EnumParams(uint methodDef) { return EnumerateTokens(metaData.EnumParams, methodDef); } public IEnumerable EnumParamProps(uint methodDef) { foreach(uint token in EnumerateTokens(metaData.EnumParams, methodDef)) { yield return GetParamProps(token); } } public uint[] EnumPermissionSets(uint token_scope_nullable, uint actions) { return EnumerateTokens(metaData.EnumPermissionSets, token_scope_nullable, actions); } public IEnumerable EnumPermissionSetProps(uint token_scope_nullable, uint actions) { foreach(uint token in EnumerateTokens(metaData.EnumPermissionSets, token_scope_nullable, actions)) { yield return GetPermissionSetProps(token); } } public uint[] EnumProperties(uint typeDef) { return EnumerateTokens(metaData.EnumProperties, typeDef); } public IEnumerable EnumPropertyProps(uint typeDef) { foreach(uint token in EnumerateTokens(metaData.EnumProperties, typeDef)) { yield return GetPropertyProps(token); } } public uint[] EnumSignatures() { return EnumerateTokens(metaData.EnumSignatures); } public uint[] EnumTypeDefs() { return EnumerateTokens(metaData.EnumTypeDefs); } public IEnumerable EnumTypeDefProps() { foreach(uint token in EnumerateTokens(metaData.EnumTypeDefs)) { yield return GetTypeDefProps(token); } } public uint[] EnumTypeRefs() { return EnumerateTokens(metaData.EnumTypeRefs); } public IEnumerable EnumTypeRefProps() { foreach(uint token in EnumerateTokens(metaData.EnumTypeRefs)) { yield return GetTypeRefProps(token); } } public uint[] EnumTypeSpecs() { return EnumerateTokens(metaData.EnumTypeSpecs); } public IEnumerable EnumTypeSpecBlobs() { foreach(uint token in EnumerateTokens(metaData.EnumTypeSpecs)) { yield return GetTypeSpecFromToken(token); } } public uint[] EnumUnresolvedMethods() { return EnumerateTokens(metaData.EnumUnresolvedMethods); } public uint[] EnumUserStrings() { return EnumerateTokens(metaData.EnumUserStrings); } public IEnumerable EnumUserStringProps() { foreach(uint token in EnumerateTokens(metaData.EnumUserStrings)) { yield return GetUserString(token); } } public uint FindField(uint typeDef_nullable, string name, Blob sigBlob) { sigBlob = sigBlob ?? Blob.Empty; uint fieldDef; metaData.FindField(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out fieldDef); return fieldDef; } public FieldProps FindFieldProps(uint typeDef_nullable, string name, Blob sigBlob) { return GetFieldProps(FindField(typeDef_nullable, name, sigBlob)); } public uint FindMember(uint typeDef_nullable, string name, Blob sigBlob) { sigBlob = sigBlob ?? Blob.Empty; uint memberDef; metaData.FindMember(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out memberDef); return memberDef; } public MemberProps FindMemberProps(uint typeDef_nullable, string name, Blob sigBlob) { return GetMemberProps(FindMember(typeDef_nullable, name, sigBlob)); } public uint FindMemberRef(uint typeRef_nullable, string name, Blob sigBlob) { sigBlob = sigBlob ?? Blob.Empty; uint memberRef; metaData.FindMemberRef(typeRef_nullable, name, sigBlob.Adress, sigBlob.Size, out memberRef); return memberRef; } public MemberRefProps FindMemberRefProps(uint typeRef_nullable, string name, Blob sigBlob) { return GetMemberRefProps(FindMemberRef(typeRef_nullable, name, sigBlob)); } public uint FindMethod(uint typeDef_nullable, string name, Blob sigBlob) { sigBlob = sigBlob ?? Blob.Empty; uint methodDef; metaData.FindMethod(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out methodDef); return methodDef; } public MethodProps FindMethodProps(uint typeDef_nullable, string name, Blob sigBlob) { return GetMethodProps(FindMethod(typeDef_nullable, name, sigBlob)); } public uint FindTypeDefByName(string name, uint typeDef_typeRef_enclosingClass_nullable) { uint typeDef; metaData.FindTypeDefByName(name, typeDef_typeRef_enclosingClass_nullable, out typeDef); return typeDef; } public TypeDefProps FindTypeDefPropsByName(string name, uint typeDef_typeRef_enclosingClass_nullable) { return GetTypeDefProps(FindTypeDefByName(name, typeDef_typeRef_enclosingClass_nullable)); } public uint FindTypeRef(uint moduleRef_assemblyRef_typeRef_scope, string name) { uint typeRef; metaData.FindTypeRef(moduleRef_assemblyRef_typeRef_scope, name, out typeRef); return typeRef; } public TypeRefProps FindTypeRefProps(uint moduleRef_assemblyRef_typeRef_scope, string name) { return GetTypeRefProps(FindTypeRef(moduleRef_assemblyRef_typeRef_scope, name)); } public ClassLayout GetClassLayout(uint typeDef) { ClassLayout ret = new ClassLayout(); ret.TypeDef = typeDef; ret.FieldOffsets = new COR_FIELD_OFFSET[DefaultBufferSize]; uint returned; while (true) { metaData.GetClassLayout( ret.TypeDef, out ret.PackSize, ret.FieldOffsets, (uint)ret.FieldOffsets.Length, out returned, out ret.ClassSize ); if (returned < ret.FieldOffsets.Length) break; ret.FieldOffsets = new COR_FIELD_OFFSET[ret.FieldOffsets.Length * BufferSizeMultiplier]; } Array.Resize(ref ret.FieldOffsets, (int)returned); return ret; } public Blob GetCustomAttributeByName(uint token_owner, string name) { IntPtr blobPtr; uint blobSize; metaData.GetCustomAttributeByName( token_owner, name, out blobPtr, out blobSize ); return new Blob(blobPtr, blobSize); } public CustomAttributeProps GetCustomAttributeProps(uint token) { IntPtr blobPtr; uint blobSize; CustomAttributeProps ret = new CustomAttributeProps(); ret.Token = token; metaData.GetCustomAttributeProps( ret.Token, out ret.Owner, out ret.Type, out blobPtr, out blobSize ); ret.Data = new Blob(blobPtr, blobSize); return ret; } public EventProps GetEventProps(uint eventToken) { EventProps ret = new EventProps(); ret.Event = eventToken; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { ret.OtherMethods = new uint[DefaultBufferSize]; uint returned; while(true) { metaData.GetEventProps( ret.Event, out ret.DeclaringClass, pString, pStringLenght, out stringLenght, out ret.Flags, out ret.EventType, out ret.AddMethod, out ret.RemoveMethod, out ret.FireMethod, ret.OtherMethods, (uint)ret.OtherMethods.Length, out returned ); if (returned < ret.OtherMethods.Length) break; ret.OtherMethods = new uint[ret.OtherMethods.Length * BufferSizeMultiplier]; } Array.Resize(ref ret.OtherMethods, (int)returned); }); return ret; } public Blob GetFieldMarshal(uint token) { IntPtr blobPtr; uint blobSize; metaData.GetFieldMarshal( token, out blobPtr, out blobSize ); return new Blob(blobPtr, blobSize); } public FieldProps GetFieldProps(uint fieldDef) { FieldProps ret = new FieldProps(); IntPtr sigPtr = IntPtr.Zero; uint sigSize = 0; ret.Token = fieldDef; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetFieldProps( ret.Token, out ret.DeclaringClass, pString, pStringLenght, out stringLenght, out ret.Flags, out sigPtr, out sigSize, out ret.ConstantType, out ret.ConstantPtr, out ret.ConstantStringLength ); }); ret.SigBlob = new Blob(sigPtr, sigSize); return ret; } public InterfaceImplProps GetInterfaceImplProps(uint method) { InterfaceImplProps ret = new InterfaceImplProps(); ret.Method = method; metaData.GetInterfaceImplProps( ret.Method, out ret.Class, out ret.Interface ); return ret; } public MemberProps GetMemberProps(uint token) { MemberProps ret = new MemberProps(); IntPtr sigPtr = IntPtr.Zero; uint sigSize = 0; ret.Token = token; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetMemberProps( ret.Token, out ret.Class, pString, pStringLenght, out stringLenght, out ret.Flags, out sigPtr, out sigSize, out ret.RVA, out ret.ImplFlags, out ret.ConstantType, out ret.ConstantPtr, out ret.ConstantStringLength ); }); ret.SigBlob = new Blob(sigPtr, sigSize); return ret; } public MemberRefProps GetMemberRefProps(uint token) { MemberRefProps ret = new MemberRefProps(); IntPtr sigPtr = IntPtr.Zero; uint sigSize = 0; ret.Token = token; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetMemberRefProps( token, out ret.DeclaringType, pString, pStringLenght, out stringLenght, out sigPtr, out sigSize ); }); ret.SigBlob = new Blob(sigPtr, sigSize); return ret; } public MethodProps GetMethodProps(uint methodToken) { MethodProps ret = new MethodProps(); IntPtr sigPtr = IntPtr.Zero; uint sigSize = 0; ret.Token = methodToken; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetMethodProps( ret.Token, out ret.ClassToken, pString, pStringLenght, out stringLenght, out ret.Flags, out sigPtr, out sigSize, out ret.CodeRVA, out ret.ImplFlags ); }); ret.SigBlob = new Blob(sigPtr, sigSize); return ret; } public uint GetMethodSemantics(uint methodDef, uint event_property) { uint semFlags; metaData.GetMethodSemantics(methodDef, event_property, out semFlags); return semFlags; } public uint GetModuleFromScope() { uint module; metaData.GetModuleFromScope(out module); return module; } public ModuleRefProps GetModuleRefProps(uint token) { ModuleRefProps ret = new ModuleRefProps(); ret.Token = token; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetModuleRefProps( token, pString, pStringLenght, out stringLenght ); }); return ret; } public uint GetNativeCallConvFromSig(Blob sigBlob) { uint callConv; metaData.GetNativeCallConvFromSig(sigBlob.Adress, sigBlob.Size, out callConv); return callConv; } public NestedClassProps GetNestedClassProps(uint nestedClass) { NestedClassProps ret = new NestedClassProps(); ret.NestedClass = nestedClass; metaData.GetNestedClassProps( ret.NestedClass, out ret.EnclosingClass ); return ret; } public uint GetParamForMethodIndex(uint methodToken, uint parameterSequence) { uint paramToken; metaData.GetParamForMethodIndex(methodToken, parameterSequence, out paramToken); return paramToken; } public ParamProps GetParamPropsForMethodIndex(uint methodToken, uint parameterSequence) { return GetParamProps(GetParamForMethodIndex(methodToken, parameterSequence)); } public ParamProps GetParamProps(uint paramToken) { ParamProps ret = new ParamProps(); ret.ParamDef = paramToken; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetParamProps( ret.ParamDef, out ret.MethodDef, out ret.Sequence, pString, pStringLenght, out stringLenght, out ret.Flags, out ret.ConstantType, out ret.ConstantPtr, out ret.ConstantStringLength ); }); return ret; } public PermissionSetProps GetPermissionSetProps(uint permToken) { PermissionSetProps ret = new PermissionSetProps(); IntPtr permPtr; uint permSize; ret.PermToken = permToken; metaData.GetPermissionSetProps( ret.PermToken, out ret.Action, out permPtr, out permSize ); ret.SigBlob = new Blob(permPtr, permSize); return ret; } public PinvokeMap GetPinvokeMap(uint fieldDef_methodDef) { PinvokeMap ret = new PinvokeMap(); ret.Token = fieldDef_methodDef; ret.ImportName = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetPinvokeMap( ret.Token, out ret.Flags, pString, pStringLenght, out stringLenght, out ret.ModuleRef ); }); return ret; } public PropertyProps GetPropertyProps(uint prop) { PropertyProps ret = new PropertyProps(); IntPtr sigPtr = IntPtr.Zero; uint sigSize = 0; ret.Propery = prop; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { ret.OtherMethods = new uint[DefaultBufferSize]; uint returned; while(true) { metaData.GetPropertyProps( ret.Propery, out ret.DeclaringClass, pString, pStringLenght, out stringLenght, out ret.Flags, out sigPtr, out sigSize, out ret.DefaultValueType, out ret.DefaultValuePtr, out ret.DefaultValueStringLength, out ret.SetterMethod, out ret.GetterMethod, ret.OtherMethods, (uint)ret.OtherMethods.Length, out returned ); if (returned < ret.OtherMethods.Length) break; ret.OtherMethods = new uint[ret.OtherMethods.Length * BufferSizeMultiplier]; } Array.Resize(ref ret.OtherMethods, (int)returned); }); ret.SigBlob = new Blob(sigPtr, sigSize); return ret; } public RVA GetRVA(uint methodDef_fieldDef) { RVA ret = new RVA(); ret.Token = methodDef_fieldDef; metaData.GetRVA( ret.Token, out ret.CodeRVA, out ret.ImplFlags ); return ret; } public ScopeProps GetScopeProps() { ScopeProps ret = new ScopeProps(); ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetScopeProps( pString, pStringLenght, out stringLenght, out ret.Guid ); }); return ret; } public Blob GetSigFromToken(uint token) { IntPtr sigPtr; uint sigSize; metaData.GetSigFromToken( token, out sigPtr, out sigSize ); return new Blob(sigPtr, sigSize); } public TypeDefProps GetTypeDefProps(uint typeDef) { TypeDefProps ret = new TypeDefProps(); ret.Token = typeDef; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetTypeDefProps( ret.Token, pString, pStringLenght, out stringLenght, out ret.Flags, out ret.SuperClassToken ); }); return ret; } public TypeRefProps GetTypeRefProps(uint typeRef) { TypeRefProps ret = new TypeRefProps(); ret.TypeRef = typeRef; ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetTypeRefProps( ret.TypeRef, out ret.ResolutionScope, pString, pStringLenght, out stringLenght ); }); return ret; } public Blob GetTypeSpecFromToken(uint typeSpec) { IntPtr sigPtr; uint sigSize; metaData.GetTypeSpecFromToken( typeSpec, out sigPtr, out sigSize ); return new Blob(sigPtr, sigSize); } public string GetUserString(uint stringToken) { return Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { metaData.GetUserString( stringToken, pString, pStringLenght, out stringLenght ); }); } public bool IsGlobal(uint token) { int isGlobal; metaData.IsGlobal(token, out isGlobal); return isGlobal != 0; } public bool IsValidToken(uint token) { return metaData.IsValidToken(token) != 0; } public ResolvedTypeRef ResolveTypeRef(uint typeRef, Guid riid) { ResolvedTypeRef res = new ResolvedTypeRef(); metaData.ResolveTypeRef( typeRef, ref riid, out res.Scope, out res.TypeDef ); return res; } #region Util delegate void TokenEnumerator0(ref IntPtr phEnum, uint[] token, uint maxCount, out uint fetched); uint[] EnumerateTokens(TokenEnumerator0 tokenEnumerator) { IntPtr enumerator = IntPtr.Zero; uint[] buffer = new uint[DefaultBufferSize]; uint fetched; tokenEnumerator(ref enumerator, buffer, (uint)buffer.Length, out fetched); if (fetched < buffer.Length) { // The tokens did fit the buffer Array.Resize(ref buffer, (int)fetched); } else { // The tokens did not fit the buffer -> Refetch uint actualCount; metaData.CountEnum(enumerator, out actualCount); if (actualCount > buffer.Length) { buffer = new uint[actualCount]; metaData.ResetEnum(enumerator, 0); tokenEnumerator(ref enumerator, buffer, (uint)buffer.Length, out fetched); } } metaData.CloseEnum(enumerator); return buffer; } delegate void TokenEnumerator1(ref IntPtr phEnum, T parameter, uint[] token, uint maxCount, out uint fetched); uint[] EnumerateTokens(TokenEnumerator1 tokenEnumerator, T parameter) { IntPtr enumerator = IntPtr.Zero; uint[] buffer = new uint[DefaultBufferSize]; uint fetched; tokenEnumerator(ref enumerator, parameter, buffer, (uint)buffer.Length, out fetched); if (fetched < buffer.Length) { // The tokens did fit the buffer Array.Resize(ref buffer, (int)fetched); } else { // The tokens did not fit the buffer -> Refetch uint actualCount; metaData.CountEnum(enumerator, out actualCount); if (actualCount > buffer.Length) { buffer = new uint[actualCount]; metaData.ResetEnum(enumerator, 0); tokenEnumerator(ref enumerator, parameter, buffer, (uint)buffer.Length, out fetched); } } metaData.CloseEnum(enumerator); return buffer; } delegate void TokenEnumerator2(ref IntPtr phEnum, T parameter1, R parameter2, uint[] token, uint maxCount, out uint fetched); uint[] EnumerateTokens(TokenEnumerator2 tokenEnumerator, T parameter1, R parameter2) { IntPtr enumerator = IntPtr.Zero; uint[] buffer = new uint[DefaultBufferSize]; uint fetched; tokenEnumerator(ref enumerator, parameter1, parameter2, buffer, (uint)buffer.Length, out fetched); if (fetched < buffer.Length) { // The tokens did fit the buffer Array.Resize(ref buffer, (int)fetched); } else { // The tokens did not fit the buffer -> Refetch uint actualCount; metaData.CountEnum(enumerator, out actualCount); if (actualCount > buffer.Length) { buffer = new uint[actualCount]; metaData.ResetEnum(enumerator, 0); tokenEnumerator(ref enumerator, parameter1, parameter2, buffer, (uint)buffer.Length, out fetched); } } metaData.CloseEnum(enumerator); return buffer; } #endregion } public class Blob { public static readonly Blob Empty = new Blob(IntPtr.Zero, 0); IntPtr adress; uint size; public IntPtr Adress { get { return adress; } } public uint Size { get { return size; } } public Blob(IntPtr adress, uint size) { this.adress = adress; this.size = size; } public byte[] GetData() { byte[] data = new byte[size]; Marshal.Copy(adress, data, 0, (int)size); return data; } } public class ClassLayout { public uint TypeDef; public uint PackSize; public COR_FIELD_OFFSET[] FieldOffsets; public uint ClassSize; } public class CustomAttributeProps { public uint Token; public uint Owner; public uint Type; public Blob Data; } public class EventProps { public uint Event; public uint DeclaringClass; public string Name; public uint Flags; public uint EventType; public uint AddMethod; public uint RemoveMethod; public uint FireMethod; public uint[] OtherMethods; } public class FieldProps { public uint Token; public string Name; public uint DeclaringClass; public uint Flags; public Blob SigBlob; public uint ConstantType; public IntPtr ConstantPtr; public uint ConstantStringLength; } public class InterfaceImplProps { public uint Method; public uint Class; public uint Interface; } public class MemberProps { public uint Token; public uint Class; public string Name; public uint Flags; public Blob SigBlob; public uint RVA; public uint ImplFlags; public uint ConstantType; public IntPtr ConstantPtr; public uint ConstantStringLength; } public class MemberRefProps { public uint Token; public uint DeclaringType; public string Name; public Blob SigBlob; } public class MethodImpl { public uint MethodBody; public uint MethodDecl; } public class MethodProps { public uint Token; public string Name; public uint ClassToken; public uint Flags; public Blob SigBlob; public uint CodeRVA; public uint ImplFlags; } public class ModuleRefProps { public uint Token; public string Name; } public class NestedClassProps { public uint NestedClass; public uint EnclosingClass; } public class ParamProps { public uint ParamDef; public uint MethodDef; public uint Sequence; public string Name; public uint Flags; public uint ConstantType; public IntPtr ConstantPtr; public uint ConstantStringLength; } public class PermissionSetProps { public uint PermToken; public uint Action; public Blob SigBlob; } public class PinvokeMap { public uint Token; public uint Flags; public string ImportName; public uint ModuleRef; } public class PropertyProps { public uint Propery; public uint DeclaringClass; public string Name; public uint Flags; public Blob SigBlob; public uint DefaultValueType; public IntPtr DefaultValuePtr; public uint DefaultValueStringLength; public uint SetterMethod; public uint GetterMethod; public uint[] OtherMethods; } public class ResolvedTypeRef { public object Scope; public uint TypeDef; } public class RVA { public uint Token; public uint CodeRVA; public uint ImplFlags; } public class ScopeProps { public string Name; public Guid Guid; } public class TypeDefProps { public uint Token; public string Name; public uint Flags; public uint SuperClassToken; } public class TypeRefProps { public uint TypeRef; public uint ResolutionScope; public string Name; } } #pragma warning restore 1591