Mercurial > pidgin
comparison src/win_gaim.c @ 7522:07156f873116
[gaim-migrate @ 8135]
Win XP no SP was not protected from dll hell
committer: Tailor Script <tailor@pidgin.im>
author | Herman Bloggs <hermanator12002@yahoo.com> |
---|---|
date | Sun, 16 Nov 2003 01:50:39 +0000 |
parents | 29d69daa1ede |
children | f1d2907db5be |
comparison
equal
deleted
inserted
replaced
7521:8beec54d1855 | 7522:07156f873116 |
---|---|
26 #include <fcntl.h> | 26 #include <fcntl.h> |
27 #include <stdlib.h> | 27 #include <stdlib.h> |
28 #include <string.h> | 28 #include <string.h> |
29 #include <stdio.h> | 29 #include <stdio.h> |
30 | 30 |
31 typedef int (CALLBACK* LPFNGAIMMAIN)(HINSTANCE, int, char**); | |
32 typedef void (CALLBACK* LPFNSETDLLDIRECTORY)(LPCTSTR); | |
33 | |
31 /* | 34 /* |
32 * PROTOTYPES | 35 * PROTOTYPES |
33 */ | 36 */ |
34 static int (*gaim_main)( HINSTANCE, int, char** ) = NULL; | 37 static LPFNGAIMMAIN gaim_main = NULL; |
35 static void (*MySetDllDirectory)(LPCTSTR lpPathName) = NULL; | 38 static LPFNSETDLLDIRECTORY MySetDllDirectory = NULL; |
36 | 39 |
37 | 40 |
38 static BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) { | 41 static BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) { |
39 HKEY hkey; | 42 HKEY hkey; |
40 BOOL ret = FALSE; | 43 BOOL ret = FALSE; |
44 sub_key, | 47 sub_key, |
45 0, KEY_QUERY_VALUE, &hkey)) { | 48 0, KEY_QUERY_VALUE, &hkey)) { |
46 if(ERROR_SUCCESS == (retv=RegQueryValueEx(hkey, val_name, 0, NULL, data, data_len))) | 49 if(ERROR_SUCCESS == (retv=RegQueryValueEx(hkey, val_name, 0, NULL, data, data_len))) |
47 ret = TRUE; | 50 ret = TRUE; |
48 else | 51 else |
49 ret = FALSE; | 52 printf("Could not read reg key '%s' subkey '%s' value: '%s'\nError: %u\n", |
53 ((key == HKEY_LOCAL_MACHINE) ? "HKLM" : (key == HKEY_CURRENT_USER) ? "HKCU" : "???"), | |
54 sub_key, val_name, (UINT)GetLastError()); | |
50 RegCloseKey(key); | 55 RegCloseKey(key); |
51 } | 56 } |
57 else | |
58 printf("Could not open reg subkey: %s\nError: %u\n", sub_key, (UINT)GetLastError()); | |
59 | |
52 return ret; | 60 return ret; |
53 } | 61 } |
54 | 62 |
55 static void run_dll_prep() { | 63 static void dll_prep() { |
56 char gtkpath[MAX_PATH]; | 64 char gtkpath[MAX_PATH]; |
57 char path[MAX_PATH]; | 65 char path[MAX_PATH]; |
58 DWORD plen = MAX_PATH; | 66 DWORD plen = MAX_PATH; |
59 int gotreg=FALSE; | 67 int gotreg=FALSE; |
60 HKEY hkey; | 68 HKEY hkey; |
84 } | 92 } |
85 else | 93 else |
86 strcat(path, "\\lib"); | 94 strcat(path, "\\lib"); |
87 } | 95 } |
88 | 96 |
89 if((hmod=LoadLibrary("kernel32.dll"))) { | 97 printf("GTK+ path found: %s\n", path); |
90 MySetDllDirectory = (void*)GetProcAddress(hmod, "SetDllDirectory"); | 98 |
91 } | 99 if((hmod=GetModuleHandle("kernel32.dll"))) { |
92 | 100 MySetDllDirectory = (LPFNSETDLLDIRECTORY)GetProcAddress(hmod, "SetDllDirectory"); |
93 /* For Windows XP SP1 / Server 2003 we use SetDllDirectory to avoid dll hell */ | 101 if(!MySetDllDirectory) |
94 if(MySetDllDirectory) | 102 printf("SetDllDirectory not supported\n"); |
103 } | |
104 else | |
105 printf("Error getting kernel32.dll module handle\n"); | |
106 | |
107 /* For Windows XP SP1+ / Server 2003 we use SetDllDirectory to avoid dll hell */ | |
108 if(MySetDllDirectory) { | |
109 printf("Using SetDllDirectory\n"); | |
95 MySetDllDirectory(path); | 110 MySetDllDirectory(path); |
96 /* For the rest, we set the current directory */ | 111 } |
112 | |
113 /* For the rest, we set the current directory and make sure SafeDllSearch is set | |
114 to 0 where needed. */ | |
97 else { | 115 else { |
98 OSVERSIONINFO osinfo; | 116 OSVERSIONINFO osinfo; |
99 | 117 |
118 printf("Setting current directory to GTK+ dll directory\n"); | |
100 SetCurrentDirectory(path); | 119 SetCurrentDirectory(path); |
101 /* For Windows 2000 SP3 and higher: | 120 /* For Windows 2000 (SP3+) / WinXP (No SP): |
102 * If SafeDllSearchMode is set to 1, Windows system directories are | 121 * If SafeDllSearchMode is set to 1, Windows system directories are |
103 * searched for dlls before the current directory. Therefore we set it | 122 * searched for dlls before the current directory. Therefore we set it |
104 * to 0. | 123 * to 0. |
105 */ | 124 */ |
106 osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | 125 osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
107 GetVersionEx(&osinfo); | 126 GetVersionEx(&osinfo); |
108 if(osinfo.dwMajorVersion == 5 && | 127 if((osinfo.dwMajorVersion == 5 && |
109 osinfo.dwMinorVersion == 0 && | 128 osinfo.dwMinorVersion == 0 && |
110 strcmp(osinfo.szCSDVersion, "Service Pack 3") >= 0) { | 129 strcmp(osinfo.szCSDVersion, "Service Pack 3") >= 0) || |
111 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, | 130 (osinfo.dwMajorVersion == 5 && |
112 "System\\CurrentControlSet\\Control\\Session Manager", | 131 osinfo.dwMinorVersion == 1 && |
113 0, KEY_SET_VALUE, &hkey)) { | 132 strcmp(osinfo.szCSDVersion, "") >= 0) |
114 DWORD regval = 0; | 133 ) { |
115 RegSetValueEx(hkey, | 134 DWORD regval = 1; |
116 "SafeDllSearchMode", | 135 DWORD reglen = sizeof(DWORD); |
117 0, | 136 |
118 REG_DWORD, | 137 printf("Using Win2k (SP3+) / WinXP (No SP).. Checking SafeDllSearch\n"); |
119 (LPBYTE) ®val, | 138 read_reg_string(HKEY_LOCAL_MACHINE, |
120 sizeof(regval)); | 139 "System\\CurrentControlSet\\Control\\Session Manager", |
121 RegCloseKey(hkey); | 140 "SafeDllSearchMode", |
141 (LPBYTE)®val, | |
142 ®len); | |
143 | |
144 if(regval != 0) { | |
145 printf("Trying to set SafeDllSearchMode to 0\n"); | |
146 regval = 0; | |
147 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, | |
148 "System\\CurrentControlSet\\Control\\Session Manager", | |
149 0, KEY_SET_VALUE, &hkey) == ERROR_SUCCESS) { | |
150 if(RegSetValueEx(hkey, | |
151 "SafeDllSearchMode", | |
152 0, | |
153 REG_DWORD, | |
154 (LPBYTE) ®val, | |
155 sizeof(DWORD)) != ERROR_SUCCESS) | |
156 printf("Error writing SafeDllSearchMode. Error: %u\n", | |
157 (UINT)GetLastError()); | |
158 RegCloseKey(hkey); | |
159 } | |
160 else | |
161 printf("Error opening Session Manager key for writing. Error: %u\n", | |
162 (UINT)GetLastError()); | |
122 } | 163 } |
123 } | 164 else |
165 printf("SafeDllSearchMode is set to 0\n"); | |
166 }/*end else*/ | |
124 } | 167 } |
125 } | 168 } |
126 | 169 |
127 static char* wgaim_lcid_to_posix(LCID lcid) { | 170 static char* wgaim_lcid_to_posix(LCID lcid) { |
128 switch(lcid) { | 171 switch(lcid) { |
169 - Check LANG env var | 212 - Check LANG env var |
170 - Check NSIS Installer Language reg value | 213 - Check NSIS Installer Language reg value |
171 - Use default user locale | 214 - Use default user locale |
172 */ | 215 */ |
173 static void wgaim_set_locale() { | 216 static void wgaim_set_locale() { |
174 HKEY hkey; | 217 char data[10]; |
218 DWORD datalen = 10; | |
175 char* locale=NULL; | 219 char* locale=NULL; |
176 char envstr[25]; | 220 char envstr[25]; |
177 LCID lcid; | 221 LCID lcid; |
178 | 222 |
179 /* Check if user set LANG env var */ | 223 /* Check if user set LANG env var */ |
180 if((locale = (char*)getenv("LANG"))) { | 224 if((locale = (char*)getenv("LANG"))) { |
181 goto finish; | 225 goto finish; |
182 } | 226 } |
183 | 227 |
184 /* Check reg key set at install time */ | 228 if(read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\gaim", "Installer Language", (LPBYTE)&data, &datalen)) { |
185 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, | 229 if((locale = wgaim_lcid_to_posix(atoi(data)))) |
186 "SOFTWARE\\gaim", | 230 goto finish; |
187 0, KEY_QUERY_VALUE, &hkey)) { | |
188 BYTE data[10]; | |
189 DWORD ds = 10; | |
190 if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Installer Language", 0, NULL, (LPBYTE)&data, &ds)) { | |
191 if((locale = wgaim_lcid_to_posix(atoi(data)))) | |
192 goto finish; | |
193 } | |
194 } | 231 } |
195 | 232 |
196 lcid = GetUserDefaultLCID(); | 233 lcid = GetUserDefaultLCID(); |
197 if((locale = wgaim_lcid_to_posix(lcid))) | 234 if((locale = wgaim_lcid_to_posix(lcid))) |
198 goto finish; | 235 goto finish; |
199 | 236 |
200 finish: | 237 finish: |
201 if(!locale) | 238 if(!locale) |
202 locale = "en"; | 239 locale = "en"; |
203 | 240 |
204 sprintf(envstr, "LANG=%s", locale); | 241 snprintf(envstr, 25, "LANG=%s", locale); |
242 printf("Setting locale: %s\n", envstr); | |
205 putenv(envstr); | 243 putenv(envstr); |
206 } | 244 } |
207 | 245 |
208 | 246 |
209 #ifdef __GNUC__ | 247 #ifdef __GNUC__ |
220 { | 258 { |
221 char errbuf[512]; | 259 char errbuf[512]; |
222 char gaimdir[MAX_PATH]; | 260 char gaimdir[MAX_PATH]; |
223 HMODULE hmod; | 261 HMODULE hmod; |
224 | 262 |
225 /* If GAIM_NO_DLL_CHECK is set, don't run the dll check */ | |
226 if(!getenv("GAIM_NO_DLL_CHECK")) | |
227 run_dll_prep(); | |
228 | |
229 /* Load exception handler if we have it */ | 263 /* Load exception handler if we have it */ |
230 if(GetModuleFileName(NULL, gaimdir, MAX_PATH) != 0) { | 264 if(GetModuleFileName(NULL, gaimdir, MAX_PATH) != 0) { |
231 char *tmp = gaimdir; | 265 char *tmp = gaimdir; |
232 char *prev = NULL; | 266 char *prev = NULL; |
233 | 267 |
236 tmp+=1; | 270 tmp+=1; |
237 } | 271 } |
238 if(prev) { | 272 if(prev) { |
239 prev[0] = '\0'; | 273 prev[0] = '\0'; |
240 strcat(gaimdir, "\\exchndl.dll"); | 274 strcat(gaimdir, "\\exchndl.dll"); |
241 LoadLibrary(gaimdir); | 275 if(LoadLibrary(gaimdir)) |
276 printf("Loaded exchndl.dll\n"); | |
242 } | 277 } |
243 } | 278 } |
244 else { | 279 else { |
245 snprintf(errbuf, 512, "Error getting module filename. Error: %u", (UINT)GetLastError()); | 280 snprintf(errbuf, 512, "Error getting module filename. Error: %u", (UINT)GetLastError()); |
246 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); | 281 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); |
247 } | 282 } |
248 | 283 |
249 /* Set Gaim locale */ | 284 if(!getenv("GAIM_NO_DLL_CHECK")) |
285 dll_prep(); | |
286 | |
250 wgaim_set_locale(); | 287 wgaim_set_locale(); |
251 | |
252 /* Set global file mode to binary so that we don't do any dos file translations */ | |
253 _fmode = _O_BINARY; | |
254 | 288 |
255 /* Now we are ready for Gaim .. */ | 289 /* Now we are ready for Gaim .. */ |
256 if((hmod=LoadLibrary("gaim.dll"))) { | 290 if((hmod=LoadLibrary("gaim.dll"))) { |
257 gaim_main = (void*)GetProcAddress(hmod, "gaim_main"); | 291 gaim_main = (LPFNGAIMMAIN)GetProcAddress(hmod, "gaim_main"); |
258 } | 292 } |
259 | 293 |
260 if(!gaim_main) { | 294 if(!gaim_main) { |
261 snprintf(errbuf, 512, "Error loading gaim.dll. Error: %u", (UINT)GetLastError()); | 295 snprintf(errbuf, 512, "Error loading gaim.dll. Error: %u", (UINT)GetLastError()); |
262 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); | 296 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); |