aboutsummaryrefslogtreecommitdiff
path: root/Utils/src/Native
diff options
context:
space:
mode:
Diffstat (limited to 'Utils/src/Native')
-rw-r--r--Utils/src/Native/SafeLibraryHandle.cs220
-rw-r--r--Utils/src/Native/SafeMethodHandle.cs61
2 files changed, 0 insertions, 281 deletions
diff --git a/Utils/src/Native/SafeLibraryHandle.cs b/Utils/src/Native/SafeLibraryHandle.cs
deleted file mode 100644
index 4772bd4..0000000
--- a/Utils/src/Native/SafeLibraryHandle.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Utils
-* File: SafeLibraryHandle.cs
-*
-* SafeLibraryHandle.cs is part of VNLib.Utils which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Utils is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published
-* by the Free Software Foundation, either version 2 of the License,
-* or (at your option) any later version.
-*
-* VNLib.Utils is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/.
-*/
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Diagnostics.CodeAnalysis;
-
-using VNLib.Utils.Extensions;
-
-namespace VNLib.Utils.Native
-{
- /// <summary>
- /// Represents a safe handle to a native library loaded to the current process
- /// </summary>
- public sealed class SafeLibraryHandle : SafeHandle
- {
- ///<inheritdoc/>
- public override bool IsInvalid => handle == IntPtr.Zero;
-
- private SafeLibraryHandle(IntPtr libHandle) : base(IntPtr.Zero, true)
- {
- //Init handle
- SetHandle(libHandle);
- }
-
- /// <summary>
- /// Finds and loads the specified native libary into the current process by its name at runtime
- /// </summary>
- /// <param name="libPath">The path (or name of libary) to search for</param>
- /// <param name="searchPath">
- /// The <see cref="DllImportSearchPath"/> used to search for libaries
- /// within the current filesystem
- /// </param>
- /// <returns>The loaded <see cref="SafeLibraryHandle"/></returns>
- /// <exception cref="ArgumentNullException"></exception>
- /// <exception cref="DllNotFoundException"></exception>
- public static SafeLibraryHandle LoadLibrary(string libPath, DllImportSearchPath searchPath = DllImportSearchPath.ApplicationDirectory)
- {
- _ = libPath ?? throw new ArgumentNullException(nameof(libPath));
- //See if the path includes a file extension
- return TryLoadLibrary(libPath, searchPath, out SafeLibraryHandle? lib)
- ? lib
- : throw new DllNotFoundException($"The library {libPath} or one of its dependencies could not be found");
- }
-
- /// <summary>
- /// Attempts to load the specified native libary into the current process by its name at runtime
- /// </summary>
- ///<param name="libPath">The path (or name of libary) to search for</param>
- /// <param name="searchPath">
- /// The <see cref="DllImportSearchPath"/> used to search for libaries
- /// within the current filesystem
- /// </param>
- /// <param name="lib">The handle to the libary if successfully loaded</param>
- /// <returns>True if the libary was found and loaded into the current process</returns>
- public static bool TryLoadLibrary(string libPath, DllImportSearchPath searchPath, [NotNullWhen(true)] out SafeLibraryHandle? lib)
- {
- lib = null;
- //Allow full rooted paths
- if (Path.IsPathRooted(libPath))
- {
- //Attempt a native load
- if (NativeLibrary.TryLoad(libPath, out IntPtr libHandle))
- {
- lib = new(libHandle);
- return true;
- }
- return false;
- }
- //Check application directory first (including subdirectories)
- if ((searchPath & DllImportSearchPath.ApplicationDirectory) > 0)
- {
- //get the current directory
- string libDir = Directory.GetCurrentDirectory();
- if (TryLoadLibraryInternal(libDir, libPath, SearchOption.TopDirectoryOnly, out lib))
- {
- return true;
- }
- }
- //See if search in the calling assembly directory
- if ((searchPath & DllImportSearchPath.AssemblyDirectory) > 0)
- {
- //Get the calling assmblies directory
- string libDir = Assembly.GetCallingAssembly().Location;
- Debug.WriteLine("Native library searching for calling assembly location:{0} ", libDir);
- if (TryLoadLibraryInternal(libDir, libPath, SearchOption.TopDirectoryOnly, out lib))
- {
- return true;
- }
- }
- //Search system32 dir
- if ((searchPath & DllImportSearchPath.System32) > 0)
- {
- //Get the system directory
- string libDir = Environment.GetFolderPath(Environment.SpecialFolder.SystemX86);
- if (TryLoadLibraryInternal(libDir, libPath, SearchOption.TopDirectoryOnly, out lib))
- {
- return true;
- }
- }
- //Attempt a native load
- {
- if (NativeLibrary.TryLoad(libPath, out IntPtr libHandle))
- {
- lib = new(libHandle);
- return true;
- }
- return false;
- }
- }
-
- private static bool TryLoadLibraryInternal(string libDir, string libPath, SearchOption dirSearchOptions, [NotNullWhen(true)] out SafeLibraryHandle? libary)
- {
- //Try to find the libary file
- string? libFile = GetLibraryFile(libDir, libPath, dirSearchOptions);
- //Load libary
- if (libFile != null && NativeLibrary.TryLoad(libFile, out IntPtr libHandle))
- {
- libary = new SafeLibraryHandle(libHandle);
- return true;
- }
- libary = null;
- return false;
- }
- private static string? GetLibraryFile(string dirPath, string libPath, SearchOption search)
- {
- //slice the lib to its file name
- libPath = Path.GetFileName(libPath);
- libPath = Path.ChangeExtension(libPath, OperatingSystem.IsWindows() ? ".dll" : ".so");
- //Select the first file that matches the name
- return Directory.EnumerateFiles(dirPath, libPath, search).FirstOrDefault();
- }
-
- /// <summary>
- /// Loads a native method from the library of the specified name and managed delegate
- /// </summary>
- /// <typeparam name="T">The native method delegate type</typeparam>
- /// <param name="methodName">The name of the native method</param>
- /// <returns>A wapper handle around the native method delegate</returns>
- /// <exception cref="ArgumentNullException"></exception>
- /// <exception cref="ObjectDisposedException">If the handle is closed or invalid</exception>
- /// <exception cref="EntryPointNotFoundException">When the specified entrypoint could not be found</exception>
- public SafeMethodHandle<T> GetMethod<T>(string methodName) where T : Delegate
- {
- //Increment handle count before obtaining a method
- bool success = false;
- DangerousAddRef(ref success);
- if (!success)
- {
- throw new ObjectDisposedException("The libary has been released!");
- }
- try
- {
- //Get the method pointer
- IntPtr nativeMethod = NativeLibrary.GetExport(handle, methodName);
- //Get the delegate for the function pointer
- T method = Marshal.GetDelegateForFunctionPointer<T>(nativeMethod);
- return new(this, method);
- }
- catch
- {
- DangerousRelease();
- throw;
- }
- }
- /// <summary>
- /// Gets an delegate wrapper for the specified method without tracking its referrence.
- /// The caller must manage the <see cref="SafeLibraryHandle"/> referrence count in order
- /// to not leak resources or cause process corruption
- /// </summary>
- /// <typeparam name="T">The native method delegate type</typeparam>
- /// <param name="methodName">The name of the native method</param>
- /// <returns>A the delegate wrapper on the native method</returns>
- /// <exception cref="ArgumentNullException"></exception>
- /// <exception cref="ObjectDisposedException">If the handle is closed or invalid</exception>
- /// <exception cref="EntryPointNotFoundException">When the specified entrypoint could not be found</exception>
- public T DangerousGetMethod<T>(string methodName) where T : Delegate
- {
- this.ThrowIfClosed();
- //Get the method pointer
- IntPtr nativeMethod = NativeLibrary.GetExport(handle, methodName);
- //Get the delegate for the function pointer
- return Marshal.GetDelegateForFunctionPointer<T>(nativeMethod);
- }
-
- ///<inheritdoc/>
- protected override bool ReleaseHandle()
- {
- //Free the library and set the handle as invalid
- NativeLibrary.Free(handle);
- SetHandleAsInvalid();
- return true;
- }
- }
-}
diff --git a/Utils/src/Native/SafeMethodHandle.cs b/Utils/src/Native/SafeMethodHandle.cs
deleted file mode 100644
index 3ba0879..0000000
--- a/Utils/src/Native/SafeMethodHandle.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* Copyright (c) 2022 Vaughn Nugent
-*
-* Library: VNLib
-* Package: VNLib.Utils
-* File: SafeMethodHandle.cs
-*
-* SafeMethodHandle.cs is part of VNLib.Utils which is part of the larger
-* VNLib collection of libraries and utilities.
-*
-* VNLib.Utils is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published
-* by the Free Software Foundation, either version 2 of the License,
-* or (at your option) any later version.
-*
-* VNLib.Utils is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with VNLib.Utils. If not, see http://www.gnu.org/licenses/.
-*/
-
-using System;
-
-using VNLib.Utils.Resources;
-
-namespace VNLib.Utils.Native
-{
- /// <summary>
- /// Represents a handle to a <see cref="SafeLibraryHandle"/>'s
- /// native method
- /// </summary>
- /// <typeparam name="T">The native method deelgate type</typeparam>
- public class SafeMethodHandle<T> : OpenHandle where T : Delegate
- {
- private T? _method;
- private readonly SafeLibraryHandle Library;
-
- internal SafeMethodHandle(SafeLibraryHandle lib, T method)
- {
- Library = lib;
- _method = method;
- }
-
- /// <summary>
- /// A delegate to the native method
- /// </summary>
- public T? Method => _method;
-
- ///<inheritdoc/>
- protected override void Free()
- {
- //Release the method
- _method = default;
- //Decrement lib handle count
- Library.DangerousRelease();
- }
- }
-}