public static unsafe object?GetValue(MetadataImport scope, int token, RuntimeTypeHandle fieldTypeHandle, bool raw) { CorElementType corElementType = 0; long buffer = 0; int length; string? stringVal; stringVal = scope.GetDefaultValue(token, out buffer, out length, out corElementType); RuntimeType fieldType = fieldTypeHandle.GetRuntimeType(); if (fieldType.IsEnum && raw == false) { // NOTE: Unlike in `TypeBuilder.SetConstantValue`, if `fieldType` describes // a nullable enum type `Nullable<TEnum>`, we do not unpack it to `TEnum` to // successfully enter this `if` clause. Default values of `TEnum?`-typed // parameters have been reported as values of the underlying type, changing // this now might be a breaking change. long defaultValue = 0; switch (corElementType) { #region Switch case CorElementType.ELEMENT_TYPE_VOID: return(DBNull.Value); case CorElementType.ELEMENT_TYPE_CHAR: defaultValue = *(char *)&buffer; break; case CorElementType.ELEMENT_TYPE_I1: defaultValue = *(sbyte *)&buffer; break; case CorElementType.ELEMENT_TYPE_U1: defaultValue = *(byte *)&buffer; break; case CorElementType.ELEMENT_TYPE_I2: defaultValue = *(short *)&buffer; break; case CorElementType.ELEMENT_TYPE_U2: defaultValue = *(ushort *)&buffer; break; case CorElementType.ELEMENT_TYPE_I4: defaultValue = *(int *)&buffer; break; case CorElementType.ELEMENT_TYPE_U4: defaultValue = *(uint *)&buffer; break; case CorElementType.ELEMENT_TYPE_I8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_U8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_CLASS: return(null); default: throw new FormatException(SR.Arg_BadLiteralFormat); #endregion } return(RuntimeType.CreateEnum(fieldType, defaultValue)); } else if (fieldType == typeof(DateTime)) { long defaultValue = 0; switch (corElementType) { #region Switch case CorElementType.ELEMENT_TYPE_VOID: return(DBNull.Value); case CorElementType.ELEMENT_TYPE_I8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_U8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_CLASS: return(null); default: throw new FormatException(SR.Arg_BadLiteralFormat); #endregion } return(new DateTime(defaultValue)); } else { switch (corElementType) { #region Switch case CorElementType.ELEMENT_TYPE_VOID: return(DBNull.Value); case CorElementType.ELEMENT_TYPE_CHAR: return(*(char *)&buffer); case CorElementType.ELEMENT_TYPE_I1: return(*(sbyte *)&buffer); case CorElementType.ELEMENT_TYPE_U1: return(*(byte *)&buffer); case CorElementType.ELEMENT_TYPE_I2: return(*(short *)&buffer); case CorElementType.ELEMENT_TYPE_U2: return(*(ushort *)&buffer); case CorElementType.ELEMENT_TYPE_I4: return(*(int *)&buffer); case CorElementType.ELEMENT_TYPE_U4: return(*(uint *)&buffer); case CorElementType.ELEMENT_TYPE_I8: return(buffer); case CorElementType.ELEMENT_TYPE_U8: return((ulong)buffer); case CorElementType.ELEMENT_TYPE_BOOLEAN: // The boolean value returned from the metadata engine is stored as a // BOOL, which actually maps to an int. We need to read it out as an int // to avoid problems on big-endian machines. return(*(int *)&buffer != 0); case CorElementType.ELEMENT_TYPE_R4: return(*(float *)&buffer); case CorElementType.ELEMENT_TYPE_R8: return(*(double *)&buffer); case CorElementType.ELEMENT_TYPE_STRING: // A string constant can be empty but never null. // A nullref constant can only be type CorElementType.ELEMENT_TYPE_CLASS. return(stringVal == null ? string.Empty : stringVal); case CorElementType.ELEMENT_TYPE_CLASS: return(null); default: throw new FormatException(SR.Arg_BadLiteralFormat); #endregion } } }
/// <summary> /// Search assemblies in the GAC for a type with the same GUID as "typeInfoGuid" /// </summary> private static Assembly SearchForInteropAssemblyInGAC(Guid typeInfoGuid, int major, int minor) { string systemRoot = Environment.GetEnvironmentVariable("SystemRoot"); string[] files = Directory.GetFiles(systemRoot + @"\assembly\gac", "*.dll", SearchOption.AllDirectories); string regex = systemRoot + @"\assembly\gac\[^\]*\{0}.{1}"; regex = regex.Replace(@"\", @"\\"); regex = string.Format(regex, major, minor); foreach (string file in files) { if (Regex.IsMatch(file, regex)) { MetadataImport mdImport = new MetadataImport(file); System.Collections.Generic.List<uint> types = mdImport.GetTypes(); foreach (uint tkType in types) { if (mdImport.GetGuidCA(tkType) != typeInfoGuid) continue; AssemblyName name = new AssemblyName(); name.Name = Path.GetFileNameWithoutExtension(file); string regexGac = regex + @"[^_]*__(?<publicKeyToken>[^\\]*)"; string match = Regex.Match(file, regexGac).Groups["publicKeyToken"].Value; byte[] publicKeyToken = new byte[match.Length / 2]; for (int i = 0; i < publicKeyToken.Length; i++) { string b = "" + match[i * 2] + match[i * 2 + 1]; publicKeyToken[i] = byte.Parse(b, NumberStyles.HexNumber); } name.SetPublicKeyToken(publicKeyToken); name.CultureInfo = CultureInfo.InvariantCulture; return Assembly.Load(name); } } } return null; }
[System.Security.SecurityCritical] // auto-generated internal static Attribute GetCustomAttribute(RuntimeMethodInfo method) { if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0) { return(null); } #if !MONO MetadataImport scope = ModuleHandle.GetMetadataImport(method.Module.ModuleHandle.GetRuntimeModule()); #endif string entryPoint, dllName = null; int token = method.MetadataToken; PInvokeAttributes flags = 0; #if MONO ((MonoMethod)method).GetPInvoke(out flags, out entryPoint, out dllName); #else scope.GetPInvokeMap(token, out flags, out entryPoint, out dllName); #endif CharSet charSet = CharSet.None; switch (flags & PInvokeAttributes.CharSetMask) { case PInvokeAttributes.CharSetNotSpec: charSet = CharSet.None; break; case PInvokeAttributes.CharSetAnsi: charSet = CharSet.Ansi; break; case PInvokeAttributes.CharSetUnicode: charSet = CharSet.Unicode; break; case PInvokeAttributes.CharSetAuto: charSet = CharSet.Auto; break; // Invalid: default to CharSet.None default: break; } CallingConvention callingConvention = CallingConvention.Cdecl; switch (flags & PInvokeAttributes.CallConvMask) { case PInvokeAttributes.CallConvWinapi: callingConvention = CallingConvention.Winapi; break; case PInvokeAttributes.CallConvCdecl: callingConvention = CallingConvention.Cdecl; break; case PInvokeAttributes.CallConvStdcall: callingConvention = CallingConvention.StdCall; break; case PInvokeAttributes.CallConvThiscall: callingConvention = CallingConvention.ThisCall; break; case PInvokeAttributes.CallConvFastcall: callingConvention = CallingConvention.FastCall; break; // Invalid: default to CallingConvention.Cdecl default: break; } bool exactSpelling = (flags & PInvokeAttributes.NoMangle) != 0; bool setLastError = (flags & PInvokeAttributes.SupportsLastError) != 0; bool bestFitMapping = (flags & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; bool throwOnUnmappableChar = (flags & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; bool preserveSig = (method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0; return(new DllImportAttribute( dllName, entryPoint, charSet, exactSpelling, setLastError, preserveSig, callingConvention, bestFitMapping, throwOnUnmappableChar)); }
internal MetadataTables(MetadataImport import, string path, Module module) { m_import = import; m_path = path; Module = module; }
internal MetadataTables(MetadataImport import, string path, Module module) { m_import = import; m_path = path; m_module = module; }
public static unsafe object?GetValue(MetadataImport scope, int token, RuntimeTypeHandle fieldTypeHandle, bool raw) { CorElementType corElementType = 0; long buffer = 0; int length; string? stringVal = scope.GetDefaultValue(token, out buffer, out length, out corElementType); RuntimeType fieldType = fieldTypeHandle.GetRuntimeType(); if (fieldType.IsEnum && !raw) { // NOTE: Unlike in `TypeBuilder.SetConstantValue`, if `fieldType` describes // a nullable enum type `Nullable<TEnum>`, we do not unpack it to `TEnum` to // successfully enter this `if` clause. Default values of `TEnum?`-typed // parameters have been reported as values of the underlying type, changing // this now might be a breaking change. long defaultValue = 0; switch (corElementType) { #region Switch case CorElementType.ELEMENT_TYPE_VOID: return(DBNull.Value); case CorElementType.ELEMENT_TYPE_CHAR: defaultValue = *(char *)&buffer; break; case CorElementType.ELEMENT_TYPE_I1: defaultValue = *(sbyte *)&buffer; break; case CorElementType.ELEMENT_TYPE_U1: defaultValue = *(byte *)&buffer; break; case CorElementType.ELEMENT_TYPE_I2: defaultValue = *(short *)&buffer; break; case CorElementType.ELEMENT_TYPE_U2: defaultValue = *(ushort *)&buffer; break; case CorElementType.ELEMENT_TYPE_I4: defaultValue = *(int *)&buffer; break; case CorElementType.ELEMENT_TYPE_U4: defaultValue = *(uint *)&buffer; break; case CorElementType.ELEMENT_TYPE_I8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_U8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_CLASS: return(null); default: throw new FormatException(SR.Arg_BadLiteralFormat); #endregion } return(RuntimeType.CreateEnum(fieldType, defaultValue)); } else if (fieldType == typeof(DateTime)) { long defaultValue = 0; switch (corElementType) { #region Switch case CorElementType.ELEMENT_TYPE_VOID: return(DBNull.Value); case CorElementType.ELEMENT_TYPE_I8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_U8: defaultValue = buffer; break; case CorElementType.ELEMENT_TYPE_CLASS: return(null); default: throw new FormatException(SR.Arg_BadLiteralFormat); #endregion } return(new DateTime(defaultValue)); } else { return(corElementType switch { CorElementType.ELEMENT_TYPE_VOID => DBNull.Value, CorElementType.ELEMENT_TYPE_CHAR => *(char *)&buffer, CorElementType.ELEMENT_TYPE_I1 => *(sbyte *)&buffer, CorElementType.ELEMENT_TYPE_U1 => *(byte *)&buffer, CorElementType.ELEMENT_TYPE_I2 => *(short *)&buffer, CorElementType.ELEMENT_TYPE_U2 => *(ushort *)&buffer, CorElementType.ELEMENT_TYPE_I4 => *(int *)&buffer, CorElementType.ELEMENT_TYPE_U4 => *(uint *)&buffer, CorElementType.ELEMENT_TYPE_I8 => buffer, CorElementType.ELEMENT_TYPE_U8 => (ulong)buffer, CorElementType.ELEMENT_TYPE_BOOLEAN => (*(int *)&buffer != 0), CorElementType.ELEMENT_TYPE_R4 => *(float *)&buffer, CorElementType.ELEMENT_TYPE_R8 => *(double *)&buffer, CorElementType.ELEMENT_TYPE_STRING => stringVal ?? string.Empty, CorElementType.ELEMENT_TYPE_CLASS => null, _ => throw new FormatException(SR.Arg_BadLiteralFormat), });
public static MetadataTables OpenFile(string fileName) { var file = MemoryMapping.Create(fileName); var import = new MetadataImport(file.GetRange(0, (int)System.Math.Min(file.Capacity, Int32.MaxValue))); return new MetadataTables(import, fileName); }
internal MetadataTables(MetadataImport import, string path) { m_import = import; m_path = path; }
internal static Attribute GetCustomAttribute(RuntimeMethodInfo method) { if ((method.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PrivateScope) { return((Attribute)null); } MetadataImport metadataImport = ModuleHandle.GetMetadataImport(method.Module.ModuleHandle.GetRuntimeModule()); string importDll = (string)null; int metadataToken = method.MetadataToken; PInvokeAttributes attributes = PInvokeAttributes.CharSetNotSpec; string importName; metadataImport.GetPInvokeMap(metadataToken, out attributes, out importName, out importDll); CharSet charSet = CharSet.None; switch (attributes & PInvokeAttributes.CharSetMask) { case PInvokeAttributes.CharSetNotSpec: charSet = CharSet.None; break; case PInvokeAttributes.CharSetAnsi: charSet = CharSet.Ansi; break; case PInvokeAttributes.CharSetUnicode: charSet = CharSet.Unicode; break; case PInvokeAttributes.CharSetMask: charSet = CharSet.Auto; break; } CallingConvention callingConvention = CallingConvention.Cdecl; switch (attributes & PInvokeAttributes.CallConvMask) { case PInvokeAttributes.CallConvStdcall: callingConvention = CallingConvention.StdCall; break; case PInvokeAttributes.CallConvThiscall: callingConvention = CallingConvention.ThisCall; break; case PInvokeAttributes.CallConvFastcall: callingConvention = CallingConvention.FastCall; break; case PInvokeAttributes.CallConvWinapi: callingConvention = CallingConvention.Winapi; break; case PInvokeAttributes.CallConvCdecl: callingConvention = CallingConvention.Cdecl; break; } bool exactSpelling = (uint)(attributes & PInvokeAttributes.NoMangle) > 0U; bool setLastError = (uint)(attributes & PInvokeAttributes.SupportsLastError) > 0U; bool bestFitMapping = (attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; bool throwOnUnmappableChar = (attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; bool preserveSig = (uint)(method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) > 0U; return((Attribute) new DllImportAttribute(importDll, importName, charSet, exactSpelling, setLastError, preserveSig, callingConvention, bestFitMapping, throwOnUnmappableChar)); }