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) &regval, 138 read_reg_string(HKEY_LOCAL_MACHINE,
120 sizeof(regval)); 139 "System\\CurrentControlSet\\Control\\Session Manager",
121 RegCloseKey(hkey); 140 "SafeDllSearchMode",
141 (LPBYTE)&regval,
142 &reglen);
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) &regval,
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);