mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1122 lines
29 KiB
1122 lines
29 KiB
// 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 |
|
{ |
|
/// <summary>Wrapper for the unmanaged metadata API.</summary> |
|
/// <remarks>http://msdn.microsoft.com/en-us/library/ms230172.aspx</remarks> |
|
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<CustomAttributeProps> 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<EventProps> 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<FieldProps> 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<FieldProps> 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); |
|
} |
|
|
|
/// <returns>MethodDef tokens</returns> |
|
public uint[] EnumInterfaceImpls(uint typeDef) |
|
{ |
|
return EnumerateTokens(metaData.EnumInterfaceImpls, typeDef); |
|
} |
|
|
|
public IEnumerable<InterfaceImplProps> 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<MemberRefProps> 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<MemberProps> 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<MemberProps> EnumMemberPropsWithName(uint typeDef, string name) |
|
{ |
|
foreach(uint token in EnumerateTokens(metaData.EnumMembersWithName, typeDef, name)) { |
|
yield return GetMemberProps(token); |
|
} |
|
} |
|
|
|
/// <returns>MethodBody and MethodDeclaration tokens</returns> |
|
public IEnumerable<MethodImpl> 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<MethodProps> EnumMethodProps(uint typeDef) |
|
{ |
|
foreach(uint token in EnumerateTokens(metaData.EnumMethods, typeDef)) { |
|
yield return GetMethodProps(token); |
|
} |
|
} |
|
|
|
/// <returns>Events or properties</returns> |
|
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<MethodProps> 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<ModuleRefProps> EnumModuleRefProps() |
|
{ |
|
foreach(uint token in EnumerateTokens(metaData.EnumModuleRefs)) { |
|
yield return GetModuleRefProps(token); |
|
} |
|
} |
|
|
|
public uint[] EnumParams(uint methodDef) |
|
{ |
|
return EnumerateTokens(metaData.EnumParams, methodDef); |
|
} |
|
|
|
public IEnumerable<ParamProps> 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<PermissionSetProps> 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<PropertyProps> 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<TypeDefProps> EnumTypeDefProps() |
|
{ |
|
foreach(uint token in EnumerateTokens(metaData.EnumTypeDefs)) { |
|
yield return GetTypeDefProps(token); |
|
} |
|
} |
|
|
|
public uint[] EnumTypeRefs() |
|
{ |
|
return EnumerateTokens(metaData.EnumTypeRefs); |
|
} |
|
|
|
public IEnumerable<TypeRefProps> EnumTypeRefProps() |
|
{ |
|
foreach(uint token in EnumerateTokens(metaData.EnumTypeRefs)) { |
|
yield return GetTypeRefProps(token); |
|
} |
|
} |
|
|
|
public uint[] EnumTypeSpecs() |
|
{ |
|
return EnumerateTokens(metaData.EnumTypeSpecs); |
|
} |
|
|
|
public IEnumerable<Blob> 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<string> 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<T>(ref IntPtr phEnum, T parameter, uint[] token, uint maxCount, out uint fetched); |
|
|
|
uint[] EnumerateTokens<T>(TokenEnumerator1<T> 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<T,R>(ref IntPtr phEnum, T parameter1, R parameter2, uint[] token, uint maxCount, out uint fetched); |
|
|
|
uint[] EnumerateTokens<T,R>(TokenEnumerator2<T,R> 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
|
|
|