loadlib.c
来自「postgresql-odbc,跨平台应用」· C语言 代码 · 共 296 行
C
296 行
/*------ * Module: loadlib.c * * Description: This module contains routines related to * delay load import libraries. * * Comments: See "notice.txt" for copyright and license information. *------- */#include <stdio.h>#include <string.h>#include <ctype.h>#ifndef WIN32#include <errno.h>#endif /* WIN32 */#include <libpq-fe.h>#include "loadlib.h"#include "pgenlist.h"#ifdef WIN32#ifdef _MSC_VER#pragma comment(lib, "Delayimp")#pragma comment(lib, "libpq")#pragma comment(lib, "ssleay32")#ifdef _HANDLE_ENLIST_IN_DTC_#ifdef UNICODE_SUPPORT#pragma comment(lib, "pgenlist")#else#pragma comment(lib, "pgenlista")#endif /* UNICODE_SUPPORT */#endif /* _HANDLE_ENLIST_IN_DTC_ */// The followings works under VC++6.0 but doesn't work under VC++7.0.// Please add the equivalent linker options using command line etc.#if (_MSC_VER == 1200) && defined(DYNAMIC_LOAD) // VC6.0#pragma comment(linker, "/Delayload:libpq.dll")#pragma comment(linker, "/Delayload:ssleay32.dll")#ifdef UNICODE_SUPPORT#pragma comment(linker, "/Delayload:pgenlist.dll")#else#pragma comment(linker, "/Delayload:pgenlista.dll")#endif /* UNICODE_SUPPORT */#pragma comment(linker, "/Delay:UNLOAD")#endif /* _MSC_VER */#endif /* _MSC_VER */#if defined(DYNAMIC_LOAD)#define WIN_DYN_LOADCSTR libpq = "libpq";CSTR libpqdll = "LIBPQ.dll";#ifdef UNICODE_SUPPORTCSTR pgenlist = "pgenlist";CSTR pgenlistdll = "PGENLIST.dll";#elseCSTR pgenlist = "pgenlista";CSTR pgenlistdll = "PGENLISTA.dll";#endif /* UNICODE_SUPPORT */#if defined(_MSC_VER) && (_MSC_VER >= 1200)#define _MSC_DELAY_LOAD_IMPORT#endif /* MSC_VER */#endif /* DYNAMIC_LOAD */#endif /* WIN32 */#if defined(_MSC_DELAY_LOAD_IMPORT)static BOOL loaded_libpq = FALSE, loaded_ssllib = FALSE;static BOOL loaded_pgenlist = FALSE;/* * Load psqlodbc path based libpq dll. */static HMODULE MODULE_load_from_psqlodbc_path(const char *module_name){ extern HINSTANCE s_hModule; HMODULE hmodule = NULL; char szFileName[MAX_PATH]; if (GetModuleFileName(s_hModule, szFileName, sizeof(szFileName)) > 0) { char drive[_MAX_DRIVE], dir[_MAX_DIR], sysdir[MAX_PATH]; _splitpath(szFileName, drive, dir, NULL, NULL); GetSystemDirectory(sysdir, MAX_PATH); snprintf(szFileName, sizeof(szFileName), "%s%s%s.dll", drive, dir, module_name); if (_strnicmp(szFileName, sysdir, strlen(sysdir)) != 0) { hmodule = LoadLibraryEx(szFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); mylog("psqlodbc path based %s loaded module=%p\n", module_name, hmodule); } } return hmodule;}/* * Error hook function for delay load import. * Try to load psqlodbc path based libpq. * Load alternative ssl library SSLEAY32 or LIBSSL32. */#if (_MSC_VER < 1300)extern PfnDliHook __pfnDliFailureHook;extern PfnDliHook __pfnDliNotifyHook;#elseextern PfnDliHook __pfnDliFailureHook2;extern PfnDliHook __pfnDliNotifyHook2;#endif /* _MSC_VER */static FARPROC WINAPIDliErrorHook(unsigned dliNotify, PDelayLoadInfo pdli){ HMODULE hmodule = NULL; int i; static const char * const libarray[] = {"libssl32", "ssleay32"}; mylog("Dli%sHook Notify=%d %p\n", (dliFailLoadLib == dliNotify || dliFailGetProc == dliNotify) ? "Error" : "Notify", dliNotify, pdli); switch (dliNotify) { case dliNotePreLoadLibrary: case dliFailLoadLib:#if (_MSC_VER < 1300) __pfnDliNotifyHook = NULL;#else __pfnDliNotifyHook2 = NULL;#endif /* _MSC_VER */ if (_strnicmp(pdli->szDll, libpq, 5) == 0) { if (hmodule = MODULE_load_from_psqlodbc_path(libpq), NULL == hmodule) hmodule = LoadLibrary(libpq); } else if (_strnicmp(pdli->szDll, pgenlist, strlen(pgenlist)) == 0) { if (hmodule = MODULE_load_from_psqlodbc_path(pgenlist), NULL == hmodule) hmodule = LoadLibrary(pgenlist); } else { mylog("getting alternative ssl library instead of %s\n", pdli->szDll); for (i = 0; i < sizeof(libarray) / sizeof(const char * const); i++) { if (hmodule = GetModuleHandle(libarray[i]), NULL != hmodule) break; } } break; } return (FARPROC) hmodule;}/* * unload delay loaded libraries. * * Openssl Library nmake defined * ssleay32.dll is vc make, libssl32.dll is mingw make. */#ifndef SSL_DLL#define SSL_DLL "SSLEAY32.dll"#endif /* SSL_DLL */typedef BOOL (WINAPI *UnloadFunc)(LPCSTR);void CleanupDelayLoadedDLLs(void){ BOOL success;#if (_MSC_VER < 1300) /* VC6 DELAYLOAD IMPORT */ UnloadFunc func = __FUnloadDelayLoadedDLL;#else UnloadFunc func = __FUnloadDelayLoadedDLL2;#endif /* The dll names are case sensitive for the unload helper */ if (loaded_libpq) { success = (*func)(libpqdll); mylog("%s unload success=%d\n", libpqdll, success); } if (loaded_ssllib) { success = (*func)(SSL_DLL); mylog("ssldll unload success=%d\n", success); } if (loaded_pgenlist) { success = (*func)(pgenlistdll); mylog("%s unload success=%d\n", pgenlistdll, success); } return;}#elsevoid CleanupDelayLoadedDLLs(void){ return;}#endif /* _MSC_DELAY_LOAD_IMPORT */void *CALL_PQconnectdb(const char *conninfo, BOOL *libpqLoaded){ void *pqconn = NULL; *libpqLoaded = TRUE;#if defined(_MSC_DELAY_LOAD_IMPORT) __try {#if (_MSC_VER < 1300) __pfnDliFailureHook = DliErrorHook; __pfnDliNotifyHook = DliErrorHook;#else __pfnDliFailureHook2 = DliErrorHook; __pfnDliNotifyHook2 = DliErrorHook;#endif /* _MSC_VER */ pqconn = PQconnectdb(conninfo); } __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *libpqLoaded = FALSE; }#if (_MSC_VER < 1300) __pfnDliNotifyHook = NULL;#else __pfnDliNotifyHook2 = NULL;#endif /* _MSC_VER */ if (*libpqLoaded) { loaded_libpq = TRUE; /* ssllibs are already loaded by libpq if (PQgetssl(pqconn)) loaded_ssllib = TRUE; */ }#else pqconn = PQconnectdb(conninfo);#endif /* _MSC_DELAY_LOAD_IMPORT */ return pqconn;}#ifdef _HANDLE_ENLIST_IN_DTC_RETCODE CALL_EnlistInDtc(ConnectionClass *conn, void *pTra, int method){ RETCODE ret; BOOL loaded = TRUE; #if defined(_MSC_DELAY_LOAD_IMPORT) __try {#if (_MSC_VER < 1300) __pfnDliFailureHook = DliErrorHook; __pfnDliNotifyHook = DliErrorHook;#else __pfnDliFailureHook2 = DliErrorHook; __pfnDliNotifyHook2 = DliErrorHook;#endif /* _MSC_VER */ ret = EnlistInDtc(conn, pTra, method); } __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { loaded = FALSE; } if (loaded) loaded_pgenlist = TRUE;#if (_MSC_VER < 1300) __pfnDliNotifyHook = NULL;#else __pfnDliNotifyHook2 = NULL;#endif /* _MSC_VER */#else ret = EnlistInDtc(conn, pTra, method); loaded_pgenlist = TRUE;#endif /* _MSC_DELAY_LOAD_IMPORT */ return ret;}RETCODE CALL_DtcOnDisconnect(ConnectionClass *conn){ if (loaded_pgenlist) return DtcOnDisconnect(conn); return FALSE;}RETCODE CALL_DtcOnRelease(void){ if (loaded_pgenlist) return DtcOnRelease(); return FALSE;}#endif /* _HANDLE_ENLIST_IN_DTC_ */#if defined(WIN_DYN_LOAD)BOOL LIBPQ_check(){ extern HINSTANCE s_hModule; HMODULE hmodule = NULL; mylog("checking libpq library\n"); /* First search the driver's folder */ if (NULL == (hmodule = MODULE_load_from_psqlodbc_path(libpq))) /* Second try the PATH ordinarily */ hmodule = LoadLibrary(libpq); mylog("hmodule=%p\n", hmodule); if (hmodule) FreeLibrary(hmodule); return (NULL != hmodule);}#elseBOOL LIBPQ_check(){ return TRUE;}#endif /* WIN_DYN_LOAD */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?