Ejemplo n.º 1
0
        internal UnmanagedLibrary(string libraryName, SafeLibraryHandle libraryHandle)
        {
            if (string.IsNullOrWhiteSpace(libraryName))
            {
                throw new ArgumentException("A valid library name is expected.", nameof(libraryName));
            }
            if (libraryHandle.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(libraryHandle));
            }

            TraceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName);

            _handle = libraryHandle;
        }
Ejemplo n.º 2
0
            public static UnmanagedLibrary LoadUnmanagedLibrary(string libraryName)
            {
                if (string.IsNullOrWhiteSpace(libraryName))
                {
                    throw new ArgumentException("A valid library name is expected.", "libraryName");
                }

                // Now look: This method should ExpandPaths on LibraryPaths.
                // That being said, it should just enumerate
                // Path, AppBase, Arch, Compiler, LibraryName, Extension

                // Secondly, this method should try each /lib/x86_64-linux-gnu/libload.so.2 to load,
                // Third, this method should try EmbeddedResources,
                // Finally, this method fails, telling the user all libraryPaths searched.

                var libraryPaths = new List <string>(Platform.LibraryPaths);

                Platform.ExpandPaths(libraryPaths, "{System32}", Environment.SystemDirectory);

                Platform.ExpandPaths(libraryPaths, "{AppBase}", EnsureNotEndingBackSlash(
                                         AppDomain.CurrentDomain.BaseDirectory));

                Platform.ExpandPaths(libraryPaths, "{LibraryName}", libraryName);

                // Platform.ExpandPaths(libraryPaths, "{Ext}", Platform.LibraryFileExtension);

                string architecture;

                string[] architecturePaths = null;
                if (Platform.Architecture == ImageFileMachine.I386 && Environment.Is64BitProcess)
                {
                    architecture = "amd64";
                }
                else
                {
                    architecture = Enum.GetName(typeof(ImageFileMachine), Platform.Architecture).ToLower();
                }
                if (architecture == "i386")
                {
                    architecturePaths = new string[] { "i386", "x86" }
                }
                ;
                if (architecture == "amd64")
                {
                    architecturePaths = new string[] { "amd64", "x64" }
                }
                ;
                if (architecturePaths == null)
                {
                    architecturePaths = new string[] { architecture }
                }
                ;
                Platform.ExpandPaths(libraryPaths, "{Arch}", architecturePaths);

                // Expand Compiler
                Platform.ExpandPaths(libraryPaths, "{Compiler}", Platform.Compiler);

                // Now TRY the enumerated Directories for libFile.so.*

                string traceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName);

                foreach (string libraryPath in libraryPaths)
                {
                    string folder       = null;
                    string filesPattern = libraryPath;
                    int    filesPatternI;
                    if (-1 < (filesPatternI = filesPattern.LastIndexOf('\\')))
                    {
                        folder       = filesPattern.Substring(0, filesPatternI + 1);
                        filesPattern = filesPattern.Substring(filesPatternI + 1);
                    }

                    if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
                    {
                        continue;
                    }

                    string[] files = Directory.EnumerateFiles(folder, filesPattern, SearchOption.TopDirectoryOnly).ToArray();

                    foreach (string file in files)
                    {
                        // Finally, I am really loading this file
                        SafeLibraryHandle handle = OpenHandle(file);

                        if (!handle.IsNullOrInvalid())
                        {
                            Trace.TraceInformation(string.Format("{0} Loaded binary \"{1}\"",
                                                                 traceLabel, file));

                            return(new UnmanagedLibrary(libraryName, handle));
                        }
                        else
                        {
                            Exception nativeEx = GetLastLibraryError();
                            Trace.TraceInformation(string.Format("{0} Custom binary \"{1}\" not loaded: {2}",
                                                                 traceLabel, file, nativeEx.Message));
                        }
                    }
                }

                // Search ManifestResources for fileName.arch.ext
                // TODO: Enumerate ManifestResources for ZeroMQ{Arch}{Compiler}{LibraryName}{Ext}.dll
                string resourceName = string.Format("ZeroMQ.{0}.{1}{2}", libraryName, architecture, ".dll");
                string tempPath     = Path.Combine(Path.GetTempPath(), resourceName);

                if (ExtractManifestResource(resourceName, tempPath))
                {
                    SafeLibraryHandle handle = OpenHandle(tempPath);

                    if (!handle.IsNullOrInvalid())
                    {
                        Trace.TraceInformation(string.Format("{0} Loaded binary from EmbeddedResource \"{1}\" from \"{2}\".",
                                                             traceLabel, resourceName, tempPath));

                        return(new UnmanagedLibrary(libraryName, handle));
                    }
                    else
                    {
                        Trace.TraceWarning(string.Format("{0} Unable to run the extracted EmbeddedResource \"{1}\" from \"{2}\".",
                                                         traceLabel, resourceName, tempPath));
                    }
                }
                else
                {
                    Trace.TraceWarning(string.Format("{0} Unable to extract the EmbeddedResource \"{1}\" to \"{2}\".",
                                                     traceLabel, resourceName, tempPath));
                }

                var fnf404 = new StringBuilder();

                fnf404.Append(traceLabel);
                fnf404.Append(" Unable to load binary \"");
                fnf404.Append(libraryName);
                fnf404.AppendLine("\" from folders");
                foreach (string path in libraryPaths)
                {
                    fnf404.Append("\t");
                    fnf404.AppendLine(path);
                }
                fnf404.Append(" Also unable to load binary from EmbeddedResource \"");
                fnf404.Append(resourceName);
                fnf404.Append("\", from temporary path \"");
                fnf404.Append(tempPath);
                fnf404.Append("\". See Trace output for more information.");

                throw new FileNotFoundException(fnf404.ToString());
            }
Ejemplo n.º 3
0
 private static extern IntPtr GetProcAddress(SafeLibraryHandle moduleHandle, string procname);
Ejemplo n.º 4
0
 public static IntPtr LoadProcedure(SafeLibraryHandle handle, string functionName)
 {
     return(GetProcAddress(handle, functionName));
 }
Ejemplo n.º 5
0
 public static bool IsNullOrInvalid(this SafeLibraryHandle handle)
 {
     return(handle == null || handle.IsInvalid);
 }
Ejemplo n.º 6
0
 private static extern IntPtr dlsym(SafeLibraryHandle handle, IntPtr symbol);
Ejemplo n.º 7
0
 public static IntPtr LoadProcedure(SafeLibraryHandle libHandle, string functionName)
 {
     throw new NotSupportedException();
 }
Ejemplo n.º 8
0
            public static UnmanagedLibrary LoadUnmanagedLibrary(string libraryName)
            {
                if (string.IsNullOrWhiteSpace(libraryName))
                {
                    throw new ArgumentException("A valid library name is expected.", "libraryName");
                }

                // Now look: This method should ExpandPaths on LibraryPaths.
                // That being said, it should just enumerate
                // Path, AppBase, Arch, Compiler, LibraryName, Extension

                // Secondly, this method should try each /lib/x86_64-linux-gnu/libload.so.2 to load,
                // Third, this method should try EmbeddedResources,
                // Finally, this method fails, telling the user all libraryPaths searched.

                var libraryPaths = new List <string>(Platform.LibraryPaths);

                Platform.ExpandPaths(libraryPaths, "{Path}", EnumerateLibLdConf("/etc/ld.so.conf"));

                var PATHs = new List <string>();

                PATHs.Add(EnsureNotEndingSlash(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));
                PATHs.AddRange(EnumerateLibLdPATH());
                Platform.ExpandPaths(libraryPaths, "{DllPath}", PATHs);

                Platform.ExpandPaths(libraryPaths, "{AppBase}", EnsureNotEndingSlash(
                                         AppDomain.CurrentDomain.BaseDirectory));

                Platform.ExpandPaths(libraryPaths, "{LibraryName}", libraryName);

                // Platform.ExpandPaths(libraryPaths, "{Ext}", Platform.LibraryFileExtension);

                string architecture;

                string[] architecturePaths = null;
                if (Platform.Architecture == ImageFileMachine.I386 && Environment.Is64BitProcess)
                {
                    architecture = "amd64";
                }
                else
                {
                    architecture = Enum.GetName(typeof(ImageFileMachine), Platform.Architecture).ToLower();
                }
                if (architecture == "i386")
                {
                    architecturePaths = new string[] { "i386", "x86" }
                }
                ;
                if (architecture == "amd64")
                {
                    architecturePaths = new string[] { "amd64", "x64" }
                }
                ;
                if (architecturePaths == null)
                {
                    architecturePaths = new string[] { architecture }
                }
                ;
                Platform.ExpandPaths(libraryPaths, "{Arch}", architecturePaths);

                // Now TRY the enumerated Directories for libFile.so.*

                string traceLabel = string.Format("UnmanagedLibrary[{0}]", libraryName);

                foreach (string libraryPath in libraryPaths)
                {
                    string folder       = null;
                    string filesPattern = libraryPath;
                    int    filesPatternI;
                    if (-1 < (filesPatternI = filesPattern.LastIndexOf('/')))
                    {
                        folder       = filesPattern.Substring(0, filesPatternI + 1);
                        filesPattern = filesPattern.Substring(filesPatternI + 1);
                    }

                    if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
                    {
                        continue;
                    }

                    string[] files = Directory.EnumerateFiles(folder, filesPattern, SearchOption.TopDirectoryOnly).ToArray();

                    foreach (string file in files)
                    {
                        // Finally, I am really loading this file
                        SafeLibraryHandle handle = OpenHandle(file);

                        if (!handle.IsNullOrInvalid())
                        {
                            if (Platform.IsMono)
                            {
                                // This is Platform.Posix. In mono, just dlopen'ing the library doesn't work.
                                // Using DllImport("__Internal", EntryPoint = "mono_dllmap_insert") to get mono on the path.
                                MonoDllMapInsert(libraryName, file);
                            }

                            Trace.TraceInformation(string.Format("{0} Loaded binary \"{1}\"",
                                                                 traceLabel, file));

                            return(new UnmanagedLibrary(libraryName, handle));
                        }

                        handle.Close();

                        Exception nativeEx = GetLastLibraryError();
                        Trace.TraceInformation(string.Format("{0} Custom binary \"{1}\" not loaded: {2}",
                                                             traceLabel, file, nativeEx.Message));
                    }
                }

                // Search ManifestResources for fileName.arch.ext
                string resourceName = string.Format("ZeroMQ.{0}.{1}{2}", libraryName, architecture, ".so");
                string tempPath     = Path.Combine(Path.GetTempPath(), resourceName);

                if (ExtractManifestResource(resourceName, tempPath))
                {
                    // TODO: need syscall_chmod_execute(path); ?
                    SafeLibraryHandle handle = OpenHandle(tempPath);

                    if (!handle.IsNullOrInvalid())
                    {
                        if (Platform.IsMono)
                        {
                            MonoDllMapInsert(libraryName, tempPath);
                        }

                        Trace.TraceInformation(string.Format("{0} Loaded binary from EmbeddedResource \"{1}\" from \"{2}\".",
                                                             traceLabel, resourceName, tempPath));

                        return(new UnmanagedLibrary(libraryName, handle));
                    }

                    handle.Close();

                    Trace.TraceWarning(string.Format("{0} Unable to run the extracted EmbeddedResource \"{1}\" from \"{2}\".",
                                                     traceLabel, resourceName, tempPath));
                }
                else
                {
                    Trace.TraceWarning(string.Format("{0} Unable to extract the EmbeddedResource \"{1}\" to \"{2}\".",
                                                     traceLabel, resourceName, tempPath));
                }


                var fnf404 = new StringBuilder();

                fnf404.Append(traceLabel);
                fnf404.Append(" Unable to load binary \"");
                fnf404.Append(libraryName);
                fnf404.AppendLine("\" from folders");
                foreach (string path in libraryPaths)
                {
                    fnf404.Append("\t");
                    fnf404.AppendLine(path);
                }
                fnf404.Append(" Also unable to load binary from EmbeddedResource \"");
                fnf404.Append(resourceName);
                fnf404.Append("\", from temporary path \"");
                fnf404.Append(tempPath);
                fnf404.Append("\". See Trace output for more information.");

                throw new FileNotFoundException(fnf404.ToString());
            }