Mercurial > pidgin
changeset 6890:4eee806af511
[gaim-migrate @ 7436]
Checking for Dll Hell on gaim startup..
committer: Tailor Script <tailor@pidgin.im>
author | Herman Bloggs <hermanator12002@yahoo.com> |
---|---|
date | Thu, 18 Sep 2003 22:12:36 +0000 |
parents | 25bedecc872c |
children | 7d2eecf55c37 |
files | src/Makefile.mingw src/main.c src/win32/win32dep.c src/win32/win32dep.h src/win_gaim.c |
diffstat | 5 files changed, 142 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Makefile.mingw Thu Sep 18 20:57:19 2003 +0000 +++ b/src/Makefile.mingw Thu Sep 18 22:12:36 2003 +0000 @@ -168,8 +168,7 @@ -lssl3 -EXE_LIBS = -lgaim \ - -lglib-2.0 +EXE_LIBS = ## ## RULES
--- a/src/main.c Thu Sep 18 20:57:19 2003 +0000 +++ b/src/main.c Thu Sep 18 22:12:36 2003 +0000 @@ -540,7 +540,7 @@ /* FUCKING GET ME A TOWEL! */ #ifdef _WIN32 -int gaim_main(int argc, char *argv[]) +int gaim_main(HINSTANCE hint, int argc, char *argv[]) #else int main(int argc, char *argv[]) #endif @@ -806,6 +806,7 @@ } #ifdef _WIN32 + wgaim_set_hinstance(hint); wgaim_pre_plugin_init(); #endif
--- a/src/win32/win32dep.c Thu Sep 18 20:57:19 2003 +0000 +++ b/src/win32/win32dep.c Thu Sep 18 22:12:36 2003 +0000 @@ -109,6 +109,10 @@ * PUBLIC CODE */ +void wgaim_set_hinstance(HINSTANCE hint) { + gaimexe_hInstance = hint; +} + HINSTANCE wgaim_hinstance(void) { return gaimexe_hInstance; }
--- a/src/win32/win32dep.h Thu Sep 18 20:57:19 2003 +0000 +++ b/src/win32/win32dep.h Thu Sep 18 22:12:36 2003 +0000 @@ -37,6 +37,7 @@ ** win32dep.c **/ /* Windows helper functions */ +void wgaim_set_hinstance(HINSTANCE); HINSTANCE wgaim_hinstance(void); FARPROC wgaim_find_and_loadproc(char*, char*); gboolean wgaim_read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len);
--- a/src/win_gaim.c Thu Sep 18 20:57:19 2003 +0000 +++ b/src/win_gaim.c Thu Sep 18 22:12:36 2003 +0000 @@ -8,7 +8,8 @@ */ #include <windows.h> #include <stdlib.h> -#include <glib.h> +#include <string.h> +#include <stdio.h> /* * GLOBALS @@ -18,12 +19,117 @@ /* * LOCALS */ +static char msg1[] = "The following duplicate of "; +static char msg2[] = " has been found in your dll search path and will likely\x0d\x0a" + "cause Gaim to malfunction:\x0d\x0a\x0d\x0a"; + +static char msg3[] = "\x0d\x0a\x0d\x0aWould you like to rename this dll to "; +static char msg4[] = ".prob in order to avoid any possible conflicts?\x0d\x0a" + "\x0d\x0a" + "Note: Doing so will likely cause the application that installed this dll to stop functioning.\x0d\x0a" + "You may wish to inform the author of the responsible application so that future versions\x0d\x0a" + "do not cause 'Dll Hell'."; /* * PROTOTYPES */ -extern int gaim_main( int, char** ); -extern char* wgaim_install_dir(); +int (*gaim_main)( HINSTANCE, int, char** ) = NULL; + +static void check_dll(char* dll, char* orig) { + char tmp[MAX_PATH]; + char *last; + + if(SearchPath(NULL, dll, NULL, MAX_PATH, tmp, &last)) { + char* patha = (char*)malloc(strlen(orig) + strlen(dll) + 4); + strcpy(patha, orig); + strcat(patha, "\\"); + strcat(patha, dll); + /* Make sure that 2 paths are not the same */ + if(strcasecmp(patha, tmp) != 0) { + char *warning = (char*)malloc(strlen(msg1)+ + strlen(msg2)+ + strlen(msg3)+ + strlen(msg4)+ + strlen(tmp)+ + (strlen(dll)*2)+4); + sprintf(warning, "%s%s%s%s%s%s%s", msg1, dll, msg2, tmp, msg3, dll, msg4); + if(MessageBox(NULL, warning, "Gaim Warning", MB_YESNO | MB_TOPMOST)==IDYES) { + char *newname = (char*)malloc(strlen(tmp)+6); + /* Rename offending dll */ + sprintf(newname, "%s%s", tmp, ".prob"); + if(rename(tmp, newname) != 0) { + MessageBox(NULL, "Error renaming file.", NULL, MB_OK | MB_TOPMOST); + } + else + check_dll(dll, orig); + free(newname); + } + free(warning); + } + free(patha); + } +} + +static void dll_hell_check(char* gtkpath) { + HANDLE myHandle; + WIN32_FIND_DATA fd; + char* srchstr = (char*)malloc(strlen(gtkpath) + 8); + + sprintf(srchstr, "%s%s", gtkpath, "\\*.dll"); + myHandle = FindFirstFile(srchstr, &fd ); + if(myHandle != INVALID_HANDLE_VALUE) { + check_dll(fd.cFileName, gtkpath); + while(FindNextFile(myHandle, &fd)) { + check_dll(fd.cFileName, gtkpath); + } + } + free(srchstr); +} + +BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) { + HKEY hkey; + BOOL ret = FALSE; + int retv; + + if(ERROR_SUCCESS == RegOpenKeyEx(key, + sub_key, + 0, KEY_QUERY_VALUE, &hkey)) { + if(ERROR_SUCCESS == (retv=RegQueryValueEx(hkey, val_name, 0, NULL, data, data_len))) + ret = TRUE; + else { + printf("Error reading registry string value: %d\n", retv); + } + RegCloseKey(key); + } + return ret; +} + +void run_dll_check() { + char path[MAX_PATH]; + DWORD plen = MAX_PATH; + int gotreg=FALSE; + + /* Dll Hell Check.. Only run check if we are the same gaim as found in the + gaim registry key */ + if(!(gotreg = read_reg_string(HKEY_LOCAL_MACHINE, "SOFTWARE\\gaim", "", (LPBYTE)&path, &plen))) + gotreg = read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\gaim", "", (LPBYTE)&path, &plen); + + if(gotreg) { + char modpath[MAX_PATH]; + + strcat(path, "\\gaim.exe"); + GetModuleFileName(NULL, modpath, MAX_PATH); + if(strcasecmp(path, modpath) == 0) { + plen = MAX_PATH; + if(!(gotreg = read_reg_string(HKEY_LOCAL_MACHINE, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&path, &plen))) + gotreg = read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE)&path, &plen); + if(gotreg) { + strcat(path, "\\bin"); + dll_hell_check(path); + } + } + } +} #ifdef __GNUC__ # ifndef _stdcall @@ -37,14 +143,32 @@ char *lpszCmdLine, int nCmdShow) { - char* drmingw; - gaimexe_hInstance = hInstance; + char gaimdir[MAX_PATH]; + char *point; + HMODULE hmod; + + /* If GAIM_NO_DLL_CHECK is set, don't run the dll check */ + if(!getenv("GAIM_NO_DLL_CHECK")) + run_dll_check(); - /* Load exception handler if we have it */ - drmingw = g_build_filename(wgaim_install_dir(), "exchndl.dll", NULL); - LoadLibrary(drmingw); - g_free(drmingw); + /* Load exception handler if we have it */ + GetModuleFileName(NULL, gaimdir, MAX_PATH); + if((point=strstr(gaimdir, "gaim.exe"))) { + point[0] = '\0'; + strcat(gaimdir, "exchndl.dll"); + LoadLibrary(gaimdir); + } - return gaim_main (__argc, __argv); + /* Now we are ready for Gaim .. */ + if((hmod=LoadLibrary("gaim.dll"))) { + gaim_main = (void*)GetProcAddress(hmod, "gaim_main"); + } + + if(!gaim_main) { + MessageBox(NULL, "Error loading gaim.dll entry point.", NULL, MB_OK | MB_TOPMOST); + return 0; + } + else + return gaim_main (hInstance, __argc, __argv); }