/// <summary> /// Ensures that the LocalDB native API has been loaded. /// </summary> /// <returns> /// A <see cref="SafeLibraryHandle"/> pointing to the loaded /// SQL LocalDB API, if successful; otherwise <see langword="null"/>. /// </returns> private SafeLibraryHandle EnsureLocalDBLoaded() { if (_handle == null) { lock (_syncRoot) { if (_handle == null) { if (!TryGetLocalDbApiPath(out string fileName)) { return(null); } int dwFlags = 0; // Check if the local machine has KB2533623 installed in order // to use the more secure flags when calling LoadLibraryEx bool hasKB2533623; using (var hModule = NativeMethods.LoadLibraryEx(NativeMethods.KernelLibName, IntPtr.Zero, 0)) { // If the AddDllDirectory function is found then the flags are supported hasKB2533623 = NativeMethods.GetProcAddress(hModule, "AddDllDirectory") != IntPtr.Zero; } if (hasKB2533623) { // If KB2533623 is installed then specify the more secure LOAD_LIBRARY_SEARCH_DEFAULT_DIRS in dwFlags dwFlags = NativeMethods.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; } _handle = NativeMethods.LoadLibraryEx(fileName, IntPtr.Zero, dwFlags); if (_handle == null || _handle.IsInvalid) { int error = Marshal.GetLastWin32Error(); Logger.NativeApiLoadFailed(fileName, error); _handle = null; } else { Logger.NativeApiLoaded(fileName); _libraryPath = fileName; } } } } return(_handle); }
/// <summary> /// Returns a delegate of the specified type to the specified unmanaged function. /// </summary> /// <typeparam name="T">The type of the delegate to return.</typeparam> /// <param name="functionName">The name of the unmanaged function.</param> /// <returns> /// An instance of <typeparamref name="T"/> that points to the specified unmanaged /// function, if found; otherwise <see langword="null"/>. /// </returns> private T GetDelegate <T>(string functionName) where T : Delegate { Debug.Assert(functionName != null, "functionName cannot be null."); SafeLibraryHandle handle = EnsureLocalDBLoaded(); if (handle == null) { Logger.NativeApiNotLoaded(); return(null); } IntPtr ptr = NativeMethods.GetProcAddress(handle, functionName); if (ptr == IntPtr.Zero) { Logger.NativeApiFunctionNotFound(functionName); return(null); } return(Marshal.GetDelegateForFunctionPointer <T>(ptr)); }
internal static extern IntPtr GetProcAddress( SafeLibraryHandle hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);