/// <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);