Sat, 08 Jun 2013 10:26:04 +0200
Win32: strengthen DLL loading; VV: fix farstream plugins loading on win32
--- a/libpurple/win32/win32dep.c Fri Jun 07 17:45:18 2013 +0200 +++ b/libpurple/win32/win32dep.c Sat Jun 08 10:26:04 2013 +0200 @@ -450,10 +450,11 @@ g_thread_init(NULL); #endif - purple_debug_info("wpurple", "wpurple_init start\n"); + if (purple_debug_is_verbose()) + purple_debug_misc("wpurple", "wpurple_init start\n"); + purple_debug_info("wpurple", "libpurple version: " DISPLAY_VERSION "\n"); - - purple_debug_info("wpurple", "Glib:%u.%u.%u\n", + purple_debug_info("wpurple", "Glib: %u.%u.%u\n", glib_major_version, glib_minor_version, glib_micro_version); /* Winsock init */ @@ -469,7 +470,8 @@ WSACleanup(); } - purple_debug_info("wpurple", "wpurple_init end\n"); + if (purple_debug_is_verbose()) + purple_debug_misc("wpurple", "wpurple_init end\n"); } /* Windows Cleanup */
--- a/pidgin/win32/gtkwin32dep.c Fri Jun 07 17:45:18 2013 +0200 +++ b/pidgin/win32/gtkwin32dep.c Sat Jun 08 10:26:04 2013 +0200 @@ -390,7 +390,8 @@ LPFNSETLOGFILE MySetLogFile; gchar *exchndl_dll_path; - purple_debug_info("winpidgin", "winpidgin_init start\n"); + if (purple_debug_is_verbose()) + purple_debug_misc("winpidgin", "winpidgin_init start\n"); exe_hInstance = hint; @@ -415,12 +416,13 @@ #ifdef USE_GTKSPELL winpidgin_spell_init(); #endif - purple_debug_info("winpidgin", "GTK+ :%u.%u.%u\n", + purple_debug_info("winpidgin", "GTK+: %u.%u.%u\n", gtk_major_version, gtk_minor_version, gtk_micro_version); messagewin_hwnd = winpidgin_message_window_init(); - purple_debug_info("winpidgin", "winpidgin_init end\n"); + if (purple_debug_is_verbose()) + purple_debug_misc("winpidgin", "winpidgin_init end\n"); } void winpidgin_post_init(void) {
--- a/pidgin/win32/winpidgin.c Fri Jun 07 17:45:18 2013 +0200 +++ b/pidgin/win32/winpidgin.c Sat Jun 08 10:26:04 2013 +0200 @@ -60,6 +60,39 @@ return err_msg; } +static BOOL reg_value_exists(HKEY key, wchar_t *sub_key, wchar_t *val_name) { + HKEY hkey; + LONG retv; + DWORD index; + wchar_t name_buffer[100]; + BOOL exists = FALSE; + + if (sub_key == NULL || val_name == NULL) + return FALSE; + + retv = RegOpenKeyExW(key, sub_key, 0, KEY_ENUMERATE_SUB_KEYS, &hkey); + if (retv != ERROR_SUCCESS) + return FALSE; + + index = 0; + while (TRUE) + { + DWORD name_size = sizeof(name_buffer); + retv = RegEnumValueW(hkey, index++, name_buffer, &name_size, + NULL, NULL, NULL, NULL); + if (retv != ERROR_SUCCESS) + break; + name_size /= sizeof(wchar_t); + if (wcsncmp(name_buffer, val_name, name_size) == 0) { + exists = TRUE; + break; + } + } + + RegCloseKey(hkey); + return exists; +} + static BOOL read_reg_string(HKEY key, wchar_t *sub_key, wchar_t *val_name, LPBYTE data, LPDWORD data_len) { HKEY hkey; BOOL ret = FALSE; @@ -92,9 +125,7 @@ return ret; } -static BOOL common_dll_prep(const wchar_t *path) { - HMODULE hmod; - HKEY hkey; +static BOOL check_for_gtk(const wchar_t *path) { struct _stat stat_buf; wchar_t test_path[MAX_PATH + 1]; @@ -102,14 +133,58 @@ L"%s\\libgtk-win32-2.0-0.dll", path); test_path[sizeof(test_path) / sizeof(wchar_t) - 1] = L'\0'; - if (_wstat(test_path, &stat_buf) != 0) { - printf("Unable to determine GTK+ path. \n" - "Assuming GTK+ is in the PATH.\n"); - return FALSE; + return (_wstat(test_path, &stat_buf) == 0); +} + +static void common_dll_prep(const wchar_t *path) { + HMODULE hmod; + HKEY hkey; + wchar_t alt_path_buff[MAX_PATH + 1]; + wchar_t tmp_path[MAX_PATH + 1]; + /* Hold strlen("FS_PLUGIN_PATH=") + MAX_PATH + 1 */ + wchar_t farstream_path[MAX_PATH + 16]; + + if (!check_for_gtk(path)) { + const wchar_t *winpath = _wgetenv(L"PATH"); + wchar_t *delim; + + if (winpath == NULL) { + printf("Unable to determine GTK+ path (and PATH is not set).\n"); + exit(-1); + } + + path = NULL; + do + { + wcsncpy(alt_path_buff, winpath, MAX_PATH); + alt_path_buff[MAX_PATH] = L'\0'; + delim = wcschr(alt_path_buff, L';'); + if (delim != NULL) { + delim[0] = L'\0'; + winpath = wcschr(winpath, L';') + 1; + } + if (check_for_gtk(alt_path_buff)) { + path = alt_path_buff; + break; + } + } + while (delim != NULL); + + if (path == NULL) { + printf("Unable to determine GTK+ path.\n"); + exit(-1); + } } + wprintf(L"GTK+ path found: %s\n", path); - wprintf(L"GTK+ path found: %s\n", path); + wcsncpy(tmp_path, path, MAX_PATH); + tmp_path[MAX_PATH] = L'\0'; + wcsrchr(tmp_path, L'\\')[0] = L'\0'; + _snwprintf(farstream_path, sizeof(farstream_path) / sizeof(wchar_t), + L"FS_PLUGIN_PATH=%s\\lib\\farstream-0.1", tmp_path); + farstream_path[sizeof(farstream_path) / sizeof(wchar_t) - 1] = L'\0'; + _wputenv(farstream_path); if ((hmod = GetModuleHandleW(L"kernel32.dll"))) { MySetDllDirectory = (LPFNSETDLLDIRECTORY) GetProcAddress( @@ -121,7 +196,6 @@ /* For Windows XP SP1+ / Server 2003 we use SetDllDirectory to avoid dll hell */ if (MySetDllDirectory) { - printf("Using SetDllDirectory\n"); MySetDllDirectory(path); } @@ -179,11 +253,9 @@ printf("SafeDllSearchMode is set to 0\n"); }/*end else*/ } - - return TRUE; } -static BOOL dll_prep(const wchar_t *pidgin_dir) { +static void dll_prep(const wchar_t *pidgin_dir) { wchar_t path[MAX_PATH + 1]; path[0] = L'\0'; @@ -192,7 +264,7 @@ path[sizeof(path) / sizeof(wchar_t) - 1] = L'\0'; } - return common_dll_prep(path); + common_dll_prep(path); } static void portable_mode_dll_prep(const wchar_t *pidgin_dir) { @@ -214,8 +286,8 @@ path[cnt] = L'\0'; } else { printf("Unable to determine current executable path. \n" - "This will prevent the settings dir from being set.\n" - "Assuming GTK+ is in the PATH.\n"); + "This will prevent the settings dir from being set.\n"); + common_dll_prep(L'\0'); return; } @@ -229,7 +301,12 @@ wprintf(L"Setting settings dir: %s\n", path2); _wputenv(path2); - if (!dll_prep(pidgin_dir)) { + _snwprintf(path2, sizeof(path2) / sizeof(wchar_t), L"%s\\Gtk\\bin", + pidgin_dir); + path2[sizeof(path2) / sizeof(wchar_t) - 1] = L'\0'; + if (check_for_gtk(path2)) + common_dll_prep(path2); + else { /* set the GTK+ path to be \\path\to\GTK\bin */ wcscat(path, L"\\GTK\\bin"); common_dll_prep(path); @@ -444,7 +521,8 @@ printf("%s", "Looking for MIT Kerberos... "); plen = sizeof(mit_kerberos_path) / sizeof(wchar_t); - if (read_reg_string(HKEY_LOCAL_MACHINE, L"SOFTWARE\\MIT\\Kerberos", L"InstallDir", + if (reg_value_exists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\MIT\\Kerberos", L"InstallDir") && + read_reg_string(HKEY_LOCAL_MACHINE, L"SOFTWARE\\MIT\\Kerberos", L"InstallDir", (LPBYTE) &mit_kerberos_path, &plen)) { /* We *could* check for gssapi32.dll */ wprintf(L"found in '%s'.\n", mit_kerberos_path);