Give up the use of delayload hook for vc14 or later.
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Wed, 23 Nov 2016 08:25:49 +0000 (17:25 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Wed, 23 Nov 2016 08:25:49 +0000 (17:25 +0900)
loadlib.c
loadlib.h
psqlsetup.c

index 50739f2590c0a4255a44c3689d557a437673970a..b53f268dde4249dcd49d9f2781d08bfb2dbea557 100644 (file)
--- a/loadlib.c
+++ b/loadlib.c
@@ -15,8 +15,6 @@
 #include <errno.h>
 #endif /* WIN32 */
 
-#define    DELAYIMP_INSECURE_WRITABLE_HOOKS
-
 #include "loadlib.h"
 #include "pgenlist.h"
 
@@ -62,14 +60,26 @@ CSTR    psqlodbcdll = "psqlodbc30a.dll";
 #endif /* WIN32 */
 
 #if defined(_MSC_DELAY_LOAD_IMPORT)
-#if (_MSC_VER < 1300)
+/*
+ * Error hook function for delay load import.
+ * Try to load a DLL based on psqlodbc path.
+ */
+#if (_MSC_VER >= 1900)     /* vc14 or later */
+#define    TRY_DLI_HOOK \
+       __try {
+#define    RELEASE_NOTIFY_HOOK
+#elif (_MSC_VER < 1300)        /* vc6 */
+extern PfnDliHook __pfnDliFailureHook;
+extern PfnDliHook __pfnDliNotifyHook;
 #define    TRY_DLI_HOOK \
        __try { \
            __pfnDliFailureHook = DliErrorHook; \
            __pfnDliNotifyHook = DliErrorHook;
 #define    RELEASE_NOTIFY_HOOK \
            __pfnDliNotifyHook = NULL;
-#else
+#else              /* vc7 ~ 12 */
+extern PfnDliHook __pfnDliFailureHook2;
+extern PfnDliHook __pfnDliNotifyHook2;
 #define    TRY_DLI_HOOK \
        __try { \
            __pfnDliFailureHook2 = DliErrorHook; \
@@ -78,17 +88,19 @@ CSTR    psqlodbcdll = "psqlodbc30a.dll";
            __pfnDliNotifyHook2 = NULL;
 #endif /* _MSC_VER */
 #else
-#define    TRY_DLI_HOOK
+#define    TRY_DLI_HOOK \
+       __try {
 #define    RELEASE_NOTIFY_HOOK
 #endif /* _MSC_DELAY_LOAD_IMPORT */
 
 #if defined(_MSC_DELAY_LOAD_IMPORT)
 static BOOL    loaded_pgenlist = FALSE;
+static HMODULE enlist_module = NULL;
 static BOOL    loaded_psqlodbc = FALSE;
 /*
  * Load a DLL based on psqlodbc path.
  */
-static HMODULE MODULE_load_from_psqlodbc_path(const char *module_name)
+HMODULE MODULE_load_from_psqlodbc_path(const char *module_name)
 {
    extern  HINSTANCE   s_hModule;
    HMODULE hmodule = NULL;
@@ -110,17 +122,6 @@ static HMODULE MODULE_load_from_psqlodbc_path(const char *module_name)
    return hmodule;
 }
 
-/*
- * Error hook function for delay load import.
- * Try to load a DLL based on psqlodbc path.
- */
-#if (_MSC_VER < 1300)
-extern PfnDliHook __pfnDliFailureHook;
-extern PfnDliHook __pfnDliNotifyHook;
-#else
-extern PfnDliHook __pfnDliFailureHook2;
-extern PfnDliHook __pfnDliNotifyHook2;
-#endif /* _MSC_VER */
 
 static FARPROC WINAPI
 DliErrorHook(unsigned  dliNotify,
@@ -172,9 +173,17 @@ void CleanupDelayLoadedDLLs(void)
    /* The dll names are case sensitive for the unload helper */
    if (loaded_pgenlist)
    {
-       success = (*func)(pgenlistdll);
+       if (enlist_module == NULL)
+       {
+           success = (*func)(pgenlistdll);
+           mylog("%s unload success=%d\n", pgenlistdll, success);
+       }
+       else
+       {
+           FreeLibrary(enlist_module);
+           mylog("FreeLibrary %s\n", pgenlistdll);
+       }
        loaded_pgenlist = FALSE;
-       mylog("%s unload success=%d\n", pgenlistdll, success);
    }
    if (loaded_psqlodbc)
    {
@@ -191,19 +200,6 @@ void CleanupDelayLoadedDLLs(void)
 }
 #endif /* _MSC_DELAY_LOAD_IMPORT */
 
-#if defined(_MSC_DELAY_LOAD_IMPORT)
-static int filter_env2encoding(int level)
-{
-   switch (level & 0xffff)
-   {
-       case ERROR_MOD_NOT_FOUND:
-       case ERROR_PROC_NOT_FOUND:
-           return EXCEPTION_EXECUTE_HANDLER;
-   }
-   return EXCEPTION_CONTINUE_SEARCH;
-}
-#endif /* _MSC_DELAY_LOAD_IMPORT */
-
 #ifdef _HANDLE_ENLIST_IN_DTC_
 RETCODE    CALL_EnlistInDtc(ConnectionClass *conn, void *pTra, int method)
 {
@@ -217,7 +213,10 @@ RETCODE    CALL_EnlistInDtc(ConnectionClass *conn, void *pTra, int method)
            ret = EnlistInDtc(conn, pTra, method);
        }
        __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
-           loaded = FALSE;
+           if (enlist_module = MODULE_load_from_psqlodbc_path(pgenlist), NULL == enlist_module)
+               loaded = FALSE;
+           else
+               ret = EnlistInDtc(conn, pTra, method);
        }
        if (loaded)
            loaded_pgenlist = TRUE;
@@ -256,7 +255,10 @@ void   *CALL_GetTransactionObject(HRESULT *hres)
            ret = GetTransactionObject(hres);
        }
        __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
-           loaded = FALSE;
+           if (enlist_module = MODULE_load_from_psqlodbc_path(pgenlist), NULL == enlist_module)
+               loaded = FALSE;
+           else
+               ret = GetTransactionObject(hres);
        }
        if (loaded)
            loaded_pgenlist = TRUE;
index f78ae33ce93c1f6761f060cf3b3aa063cf5782fe..f0d630230d171c13bdc90b20d72ff5dc9c0a6afd 100644 (file)
--- a/loadlib.h
+++ b/loadlib.h
@@ -32,6 +32,7 @@ void  CALL_ReleaseTransactionObject(void *);
 #endif /* _HANDLE_ENLIST_IN_DTC_ */
 /* void    UnloadDelayLoadedDLLs(BOOL); */
 void   CleanupDelayLoadedDLLs(void);
+HMODULE MODULE_load_from_psqlodbc_path(const char *module_name);
 
 #ifdef __cplusplus
 }
index d2bd038348b05cb9e21b51cdf5dd5dc8937fc144..35ebb5644d93b2e07940a42a540ab0e323e816ab 100644 (file)
@@ -2,11 +2,10 @@
 
 #include   "psqlodbc.h"
 #include   "dlg_specific.h"
+#include   "loadlib.h"
 
 HINSTANCE s_hModule;       /* Saved module handle. */
 
-#ifdef PG_BIN
-
 #include <stdio.h>
 #include <string.h>
 #include <sql.h>
@@ -26,9 +25,8 @@ SQLDummyOrdinal(void)
    return SQL_SUCCESS;
 }
 
-#endif /* PG_BIN */
 
-static HINSTANCE s_hLModule = NULL;
+static HINSTANCE s_hLModule = NULL;    /* for libpq */
 static HINSTANCE s_hLModule2 = NULL;
 /* This is where the Driver Manager attaches to this Driver */
 
@@ -59,17 +57,15 @@ static void finalize_global_cs(void)
 }
 
 #ifdef UNICODE_SUPPORT
-CSTR   psqlodbcdll = "psqlodbc35w.dll";
+CSTR   psqlodbc = "psqlodbc35w";
 #else
-CSTR   psqlodbcdll = "psqlodbc30a.dll";
-
+CSTR   psqlodbc = "psqlodbc30a";
 #endif
 
 BOOL       WINAPI
 DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
 {
    char dllPath[MAX_PATH] = "";
-   char *sptr;
 
    switch (ul_reason_for_call)
    {
@@ -106,20 +102,9 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
                if (message[0])
                    MessageBox(NULL, message, "psqlsetup", MB_OK);
            }
-           if (GetModuleFileName(s_hModule, dllPath, sizeof(dllPath)) <= 0)
-           {
-               MessageBox(NULL, "GetModuleFileName error", "psqlsetup", MB_OK);
-               return TRUE;
-           }
-           if (sptr = strrchr(dllPath, '\\'), NULL == sptr)
-           {
-               MessageBox(NULL, "strrchr error", "psqlsetup", MB_OK);
-               return FALSE;
-           }
-           strcpy_s(sptr + 1, MAX_PATH - (size_t)(sptr - dllPath), psqlodbcdll);
-           if (s_hLModule2 = LoadLibraryEx(dllPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH), s_hLModule2 == NULL)
+           if (s_hLModule2 = MODULE_load_from_psqlodbc_path(psqlodbc), s_hLModule2 == NULL)
            {
-               MessageBox(NULL, dllPath, "psqlodbc load error", MB_OK);
+               MessageBox(NULL, "psqlodbc load error", "psqlsetup",  MB_OK);
                return TRUE;
            }
            break;
@@ -128,10 +113,18 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
            break;
 
        case DLL_PROCESS_DETACH:
-           if (NULL != s_hLModule2)
-               FreeLibrary(s_hLModule2);
+           mylog("DETACHING psqlsetup\n");
+           CleanupDelayLoadedDLLs();
            if (NULL != s_hLModule)
+           {
                FreeLibrary(s_hLModule);
+               mylog("FreeLibrary libpq\n");
+           }
+           if (NULL != s_hLModule2)
+           {
+               FreeLibrary(s_hLModule2);
+               mylog("FreeLibrary %s\n", psqlodbc);
+           }
            finalize_global_cs();
            return TRUE;