/pidgin/main: ce450446c56a: Win32: strengthen DLL loading; VV: f...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sat Jun 8 04:26:11 EDT 2013


Changeset: ce450446c56a9a01b0f98f9746ebd6e515493b69
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2013-06-08 10:26 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/ce450446c56a

Description:

Win32: strengthen DLL loading; VV: fix farstream plugins loading on win32

diffstat:

 libpurple/win32/win32dep.c |   10 ++-
 pidgin/win32/gtkwin32dep.c |    8 ++-
 pidgin/win32/winpidgin.c   |  112 ++++++++++++++++++++++++++++++++++++++------
 3 files changed, 106 insertions(+), 24 deletions(-)

diffs (240 lines):

diff --git a/libpurple/win32/win32dep.c b/libpurple/win32/win32dep.c
--- a/libpurple/win32/win32dep.c
+++ b/libpurple/win32/win32dep.c
@@ -450,10 +450,11 @@ void wpurple_init(void) {
 		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 @@ void wpurple_init(void) {
 		WSACleanup();
 	}
 
-	purple_debug_info("wpurple", "wpurple_init end\n");
+	if (purple_debug_is_verbose())
+		purple_debug_misc("wpurple", "wpurple_init end\n");
 }
 
 /* Windows Cleanup */
diff --git a/pidgin/win32/gtkwin32dep.c b/pidgin/win32/gtkwin32dep.c
--- a/pidgin/win32/gtkwin32dep.c
+++ b/pidgin/win32/gtkwin32dep.c
@@ -390,7 +390,8 @@ void winpidgin_init(HINSTANCE hint) {
 	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 @@ void winpidgin_init(HINSTANCE hint) {
 #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) {
diff --git a/pidgin/win32/winpidgin.c b/pidgin/win32/winpidgin.c
--- a/pidgin/win32/winpidgin.c
+++ b/pidgin/win32/winpidgin.c
@@ -60,6 +60,39 @@ static const wchar_t *get_win32_error_me
 	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 @@ static BOOL read_reg_string(HKEY key, wc
 	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 @@ static BOOL common_dll_prep(const wchar_
 		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 @@ static BOOL common_dll_prep(const wchar_
 
 	/* 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 @@ static BOOL common_dll_prep(const wchar_
 				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 @@ static BOOL dll_prep(const wchar_t *pidg
 		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 @@ static void portable_mode_dll_prep(const
 		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 @@ static void portable_mode_dll_prep(const
 	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 @@ static void winpidgin_add_stuff_to_path(
 	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);



More information about the Commits mailing list