Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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;
 }
Ejemplo n.º 7
0
 public DefaultDllImportSearchPathsAttribute(DllImportSearchPath paths)
 {
     Paths = paths;
 }
Ejemplo n.º 8
0
 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();
 }
Ejemplo n.º 10
0
        public void Ctor_Paths(DllImportSearchPath paths)
        {
            var attribute = new DefaultDllImportSearchPathsAttribute(paths);

            Assert.Equal(paths, attribute.Paths);
        }