public NetSafeLibHandle(string libPath) : base(IntPtr.Zero, true) { // [Reference] // https://docs.microsoft.com/en-US/dotnet/api/system.runtime.interopservices.dllimportsearchpath?view=netstandard-2.0 // https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order // https://docs.microsoft.com/ko-kr/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw // https://docs.microsoft.com/ko-kr/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryw // https://github.com/dotnet/runtime/blob/master/src/coreclr/src/vm/dllimport.cpp (LocalLoadLibraryHelper, LoadLibraryFromPath) // https://github.com/dotnet/runtime/blob/master/src/coreclr/src/inc/utilcode.h (GetLoadWithAlteredSearchPathFlag) // It looks like DllImportSearchPath enum is connected to LoadLibraryEx flags. // 1. Flag larger than 256 is directly mapped to LoadLibraryEx flags. // - 256: UseDllDirectoryForDependencies <-> LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR // - 512: ApplicationDirectory <-> LOAD_LIBRARY_SEARCH_APPLICATION_DIR // - 1024: UserDirectories <-> LOAD_LIBRARY_SEARCH_USER_DIRS // - 2048: System32 <-> LOAD_LIBRARY_SEARCH_SYSTEM32 // - 4096: SafeDirectories <-> LOAD_LIBRARY_SEARCH_DEFAULT_DIRS // 2. Flag smaller then 256 is loosely connected to LoadLibraryEx flags. // - 0, 8: LegacyBehavior <-> LOAD_WITH_ALTERED_SEARCH_PATH(?) // - 2, 8: AssemblyDirectory <-> LOAD_WITH_ALTERED_SEARCH_PATH(?) // 3. (Important, Undocumented?) From the function LocalLoadLibraryHelper(): // Flag smaller than 256 and larger than 256 look like mutually exclusive to each others. // Flag larger then 256 has priority over smaller than 256. const DllImportSearchPath searchPaths = DllImportSearchPath.AssemblyDirectory; handle = NativeLibrary.Load(libPath, Assembly.GetExecutingAssembly(), searchPaths); }
private static string GetCApiVersion() { unsafe { const DllImportSearchPath dllImportSearchPath = DllImportSearchPath.LegacyBehavior | DllImportSearchPath.AssemblyDirectory | DllImportSearchPath.SafeDirectories | DllImportSearchPath.System32 | DllImportSearchPath.UserDirectories | DllImportSearchPath.ApplicationDirectory | DllImportSearchPath.UseDllDirectoryForDependencies; var handle = NativeLibrary.Load(DllName, Assembly.GetExecutingAssembly(), dllImportSearchPath); var freeString = (delegate * unmanaged[Cdecl] < nint, void >)NativeLibrary.GetExport(handle, "FreeString"); var getCApiVersion = (delegate * unmanaged[Cdecl] < int *, nint >)NativeLibrary.GetExport(handle, "GetCApiVersion"); var size = 0; var str = getCApiVersion(&size); var stringResult = Marshal.PtrToStringUTF8(str, size); freeString(str); return(stringResult); } }
private static void GetDllImportSearchPathFlags(Assembly callingAssembly, out int searchPathFlags, out bool searchAssemblyDirectory) { DllImportSearchPath searchPath = DefaultDllImportSearchPath; foreach (CustomAttributeData cad in callingAssembly.CustomAttributes) { if (cad.AttributeType == typeof(DefaultDllImportSearchPathsAttribute)) { searchPath = (DllImportSearchPath)cad.ConstructorArguments[0].Value; } } searchPathFlags = (int)(searchPath & ~DllImportSearchPath.AssemblyDirectory); searchAssemblyDirectory = (searchPath & DllImportSearchPath.AssemblyDirectory) != 0; }
private static Type CreateWrapperType(Type delegateType, DllImportAttribute dllImportAttribute, DllImportSearchPath dllImportSearchPath) { TypeBuilder typeBuilder = moduleBuilder.DefineType( "PInvokeDelegateFactoryInternalWrapperType" + wrapperTypes.Count); MethodInfo methodInfo = delegateType.GetMethod("Invoke"); ParameterInfo[] parameterInfos = methodInfo.GetParameters(); int parameterCount = parameterInfos.GetLength(0); Type[] parameterTypes = new Type[parameterCount]; for (int i = 0; i < parameterCount; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } MethodBuilder methodBuilder = typeBuilder.DefinePInvokeMethod( dllImportAttribute.EntryPoint, dllImportAttribute.Value, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, methodInfo.ReturnType, parameterTypes, dllImportAttribute.CallingConvention, dllImportAttribute.CharSet); methodBuilder.SetCustomAttribute(new CustomAttributeBuilder( typeof(DefaultDllImportSearchPathsAttribute).GetConstructor( new Type[] { typeof(DllImportSearchPath) }), new object[] { dllImportSearchPath })); foreach (ParameterInfo parameterInfo in parameterInfos) { methodBuilder.DefineParameter(parameterInfo.Position + 1, parameterInfo.Attributes, parameterInfo.Name); } if (dllImportAttribute.PreserveSig) { methodBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig); } return(typeBuilder.CreateType()); }
public static void CreateDelegate <T>(DllImportAttribute dllImportAttribute, out T newDelegate, DllImportSearchPath dllImportSearchPath = DllImportSearchPath.System32) where T : class { Type wrapperType; Pair <DllImportAttribute, Type> key = new Pair <DllImportAttribute, Type>(dllImportAttribute, typeof(T)); wrapperTypes.TryGetValue(key, out wrapperType); if (wrapperType == null) { wrapperType = CreateWrapperType(typeof(T), dllImportAttribute, dllImportSearchPath); wrapperTypes.Add(key, wrapperType); } newDelegate = Delegate.CreateDelegate(typeof(T), wrapperType, dllImportAttribute.EntryPoint) as T; }
public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths) { _paths = paths; }
public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths) { Paths = paths; }
internal DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths) { _paths = paths; }
/// <summary>Initializes a new instance of the <see cref="T:System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute" /> class, specifying the paths to use when searching for the targets of platform invokes. </summary><param name="paths">A bitwise combination of enumeration values that specify the paths that the LoadLibraryEx function searches during platform invokes. </param> public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths) { throw new NotImplementedException(); }
public void Ctor_Paths(DllImportSearchPath paths) { var attribute = new DefaultDllImportSearchPathsAttribute(paths); Assert.Equal(paths, attribute.Paths); }