﻿// Decompiled with JetBrains decompiler
// Type: System.Runtime.InteropServices.DllImportAttribute
// Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 255ABCDF-D9D6-4E3D-BAD4-F74D4CE3D7A8
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll

using System;
using System.Reflection;
using System.Runtime;
using System.Security;

namespace System.Runtime.InteropServices
{
  /// <summary>
  /// Indicates that the attributed method is exposed by an unmanaged dynamic-link library (DLL) as a static entry point.
  /// </summary>
  [AttributeUsage(AttributeTargets.Method, Inherited = false)]
  [ComVisible(true)]
  [__DynamicallyInvokable]
  public sealed class DllImportAttribute : Attribute
  {
    internal string _val;
    /// <summary>
    /// Indicates the name or ordinal of the DLL entry point to be called.
    /// </summary>
    [__DynamicallyInvokable]
    public string EntryPoint;
    /// <summary>
    /// Indicates how to marshal string parameters to the method and controls name mangling.
    /// </summary>
    [__DynamicallyInvokable]
    public CharSet CharSet;
    /// <summary>
    /// Indicates whether the callee calls the SetLastError Win32 API function before returning from the attributed method.
    /// </summary>
    [__DynamicallyInvokable]
    public bool SetLastError;
    /// <summary>
    /// Controls whether the <see cref="F:System.Runtime.InteropServices.DllImportAttribute.CharSet"/> field causes the common language runtime to search an unmanaged DLL for entry-point names other than the one specified.
    /// </summary>
    [__DynamicallyInvokable]
    public bool ExactSpelling;
    /// <summary>
    /// Indicates whether unmanaged methods that have HRESULT or retval return values are directly translated or whether HRESULT or retval return values are automatically converted to exceptions.
    /// </summary>
    [__DynamicallyInvokable]
    public bool PreserveSig;
    /// <summary>
    /// Indicates the calling convention of an entry point.
    /// </summary>
    [__DynamicallyInvokable]
    public CallingConvention CallingConvention;
    /// <summary>
    /// Enables or disables best-fit mapping behavior when converting Unicode characters to ANSI characters.
    /// </summary>
    [__DynamicallyInvokable]
    public bool BestFitMapping;
    /// <summary>
    /// Enables or disables the throwing of an exception on an unmappable Unicode character that is converted to an ANSI "?" character.
    /// </summary>
    [__DynamicallyInvokable]
    public bool ThrowOnUnmappableChar;

    /// <summary>
    /// Gets the name of the DLL file that contains the entry point.
    /// </summary>
    /// 
    /// <returns>
    /// The name of the DLL file that contains the entry point.
    /// </returns>
    [__DynamicallyInvokable]
    public string Value
    {
      [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
      {
        return this._val;
      }
    }

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    internal DllImportAttribute(string dllName, string entryPoint, CharSet charSet, bool exactSpelling, bool setLastError, bool preserveSig, CallingConvention callingConvention, bool bestFitMapping, bool throwOnUnmappableChar)
    {
      this._val = dllName;
      this.EntryPoint = entryPoint;
      this.CharSet = charSet;
      this.ExactSpelling = exactSpelling;
      this.SetLastError = setLastError;
      this.PreserveSig = preserveSig;
      this.CallingConvention = callingConvention;
      this.BestFitMapping = bestFitMapping;
      this.ThrowOnUnmappableChar = throwOnUnmappableChar;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Runtime.InteropServices.DllImportAttribute"/> class with the name of the DLL containing the method to import.
    /// </summary>
    /// <param name="dllName">The name of the DLL that contains the unmanaged method. This can include an assembly display name, if the DLL is included in an assembly.</param>
    [__DynamicallyInvokable]
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    public DllImportAttribute(string dllName)
    {
      this._val = dllName;
    }

    [SecurityCritical]
    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 = (attributes & PInvokeAttributes.NoMangle) != PInvokeAttributes.CharSetNotSpec;
      bool setLastError = (attributes & PInvokeAttributes.SupportsLastError) != PInvokeAttributes.CharSetNotSpec;
      bool bestFitMapping = (attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled;
      bool throwOnUnmappableChar = (attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled;
      bool preserveSig = (method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != MethodImplAttributes.IL;
      return (Attribute) new DllImportAttribute(importDll, importName, charSet, exactSpelling, setLastError, preserveSig, callingConvention, bestFitMapping, throwOnUnmappableChar);
    }

    internal static bool IsDefined(RuntimeMethodInfo method)
    {
      return (method.Attributes & MethodAttributes.PinvokeImpl) != MethodAttributes.PrivateScope;
    }
  }
}
