Esempio n. 1
0
        internal static IntPtr LoadLibraryByName(string libraryName, Assembly assembly, DllImportSearchPath?searchPath, bool throwOnError)
        {
            // First checks if a default dllImportSearchPathFlags was passed in, if so, use that value.
            // Otherwise checks if the assembly has the DefaultDllImportSearchPathsAttribute attribute.
            // If so, use that value.

            int  searchPathFlags;
            bool searchAssemblyDirectory;

            if (searchPath.HasValue)
            {
                searchPathFlags         = (int)(searchPath.Value & ~DllImportSearchPath.AssemblyDirectory);
                searchAssemblyDirectory = (searchPath.Value & DllImportSearchPath.AssemblyDirectory) != 0;
            }
            else
            {
                GetDllImportSearchPathFlags(assembly, out searchPathFlags, out searchAssemblyDirectory);
            }

            LoadLibErrorTracker errorTracker = default;
            IntPtr ret = LoadLibraryModuleBySearch(assembly, searchAssemblyDirectory, searchPathFlags, ref errorTracker, libraryName);

            if (throwOnError && ret == IntPtr.Zero)
            {
                errorTracker.Throw(libraryName);
            }

            return(ret);
        }
Esempio n. 2
0
        private const int LoadWithAlteredSearchPathFlag = 0x8; /* LOAD_WITH_ALTERED_SEARCH_PATH */

        private static IntPtr LoadLibraryHelper(string libraryName, int flags, ref LoadLibErrorTracker errorTracker)
        {
            IntPtr hmod;

            if (((uint)flags & 0xFFFFFF00) != 0)
            {
                hmod = Interop.Kernel32.LoadLibraryEx(libraryName, IntPtr.Zero, (int)((uint)flags & 0xFFFFFF00));
                if (hmod != IntPtr.Zero)
                {
                    return(hmod);
                }

                int lastError = Marshal.GetLastWin32Error();
                if (lastError != Interop.Errors.ERROR_INVALID_PARAMETER)
                {
                    errorTracker.TrackErrorCode(lastError);
                    return(hmod);
                }
            }

            hmod = Interop.Kernel32.LoadLibraryEx(libraryName, IntPtr.Zero, flags & 0xFF);
            if (hmod == IntPtr.Zero)
            {
                errorTracker.TrackErrorCode(Marshal.GetLastWin32Error());
            }

            return(hmod);
        }
Esempio n. 3
0
        private static IntPtr LoadFromPath(string libraryName, bool throwOnError)
        {
            LoadLibErrorTracker errorTracker = default;
            IntPtr ret = LoadLibraryHelper(libraryName, 0, ref errorTracker);

            if (throwOnError && ret == IntPtr.Zero)
            {
                errorTracker.Throw(libraryName);
            }

            return(ret);
        }
        private static IntPtr LoadLibraryHelper(string libraryName, int flags, ref LoadLibErrorTracker errorTracker)
        {
            // do the Dos/Unix conversion
            libraryName = libraryName.Replace('\\', '/');

            IntPtr ret = Interop.Sys.LoadLibrary(libraryName);

            if (ret == IntPtr.Zero)
            {
                string?message = Marshal.PtrToStringAnsi(Interop.Sys.GetLoadLibraryError());
                errorTracker.TrackErrorMessage(message);
            }

            return(ret);
        }
Esempio n. 5
0
        private static IntPtr LoadLibraryHelper(string libraryName, int flags, ref LoadLibErrorTracker errorTracker)
        {
#if PLATFORM_WINDOWS
            IntPtr ret = Interop.mincore.LoadLibraryEx(libraryName, IntPtr.Zero, flags);
            if (ret != IntPtr.Zero)
            {
                return(ret);
            }

            int lastError = Marshal.GetLastWin32Error();
            if (lastError != LoadLibErrorTracker.ERROR_INVALID_PARAMETER)
            {
                errorTracker.TrackErrorCode(lastError);
            }

            return(ret);
#else
            IntPtr ret = IntPtr.Zero;
            if (libraryName == null)
            {
                errorTracker.TrackErrorCode(LoadLibErrorTracker.ERROR_MOD_NOT_FOUND);
            }
            else if (libraryName == String.Empty)
            {
                errorTracker.TrackErrorCode(LoadLibErrorTracker.ERROR_INVALID_PARAMETER);
            }
            else
            {
                // TODO: FileDosToUnixPathA
                ret = Interop.Sys.LoadLibrary(libraryName);
                if (ret == IntPtr.Zero)
                {
                    errorTracker.TrackErrorCode(LoadLibErrorTracker.ERROR_MOD_NOT_FOUND);
                }
            }

            return(ret);
#endif
        }
Esempio n. 6
0
        internal static IntPtr LoadLibraryModuleBySearch(Assembly callingAssembly, bool searchAssemblyDirectory, int dllImportSearchPathFlags, ref LoadLibErrorTracker errorTracker, string libraryName)
        {
            IntPtr ret = IntPtr.Zero;

            int  loadWithAlteredPathFlags = 0;
            bool libNameIsRelativePath    = !Path.IsPathFullyQualified(libraryName);

            // P/Invokes are often declared with variations on the actual library name.
            // For example, it's common to leave off the extension/suffix of the library
            // even if it has one, or to leave off a prefix like "lib" even if it has one
            // (both of these are typically done to smooth over cross-platform differences).
            // We try to dlopen with such variations on the original.
            foreach (LibraryNameVariation libraryNameVariation in LibraryNameVariation.DetermineLibraryNameVariations(libraryName, libNameIsRelativePath))
            {
                string currLibNameVariation = libraryNameVariation.Prefix + libraryName + libraryNameVariation.Suffix;

                if (!libNameIsRelativePath)
                {
                    int flags = loadWithAlteredPathFlags;
                    if ((dllImportSearchPathFlags & (int)DllImportSearchPath.UseDllDirectoryForDependencies) != 0)
                    {
                        // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR is the only flag affecting absolute path. Don't OR the flags
                        // unconditionally as all absolute path P/Invokes could then lose LOAD_WITH_ALTERED_SEARCH_PATH.
                        flags |= dllImportSearchPathFlags;
                    }

                    ret = LoadLibraryHelper(currLibNameVariation, flags, ref errorTracker);
                    if (ret != IntPtr.Zero)
                    {
                        return(ret);
                    }
                }
                else if ((callingAssembly != null) && searchAssemblyDirectory)
                {
                    // Try to load the module alongside the assembly where the PInvoke was declared.
                    // This only makes sense in dynamic scenarios (JIT/interpreter), so leaving this out for now.
                }

                ret = LoadLibraryHelper(currLibNameVariation, dllImportSearchPathFlags, ref errorTracker);
                if (ret != IntPtr.Zero)
                {
                    return(ret);
                }
            }

            return(IntPtr.Zero);
        }