| 104 } |
106 } |
| 105 |
107 |
| 106 return ret; |
108 return ret; |
| 107 } |
109 } |
| 108 |
110 |
| 109 static void dll_prep() { |
111 static void common_dll_prep(const char *path) { |
| 110 char path[MAX_PATH + 1]; |
|
| 111 HMODULE hmod; |
112 HMODULE hmod; |
| 112 HKEY hkey; |
113 HKEY hkey; |
| 113 #ifdef PORTABLE |
114 |
| 114 /* We assume that GTK+ is installed under \\path\to\Pidgin\..\GTK |
|
| 115 * First we find \\path\to |
|
| 116 */ |
|
| 117 if (GetModuleFileName(NULL, path, MAX_PATH) != 0) { |
|
| 118 char *tmp = path; |
|
| 119 char *prev = NULL; |
|
| 120 char *prev2 = NULL; |
|
| 121 |
|
| 122 while ((tmp = strchr(tmp, '\\'))) { |
|
| 123 prev2 = prev; |
|
| 124 prev = tmp; |
|
| 125 tmp++; |
|
| 126 } |
|
| 127 |
|
| 128 if (prev2) { |
|
| 129 prev2[0] = '\0'; |
|
| 130 } |
|
| 131 } else { |
|
| 132 printf("Unable to determine current executable path. \n" |
|
| 133 "This will prevent the settings dir from being set.\n" |
|
| 134 "Assuming GTK+ is in the PATH.\n"); |
|
| 135 } |
|
| 136 |
|
| 137 if (path) { |
|
| 138 /* Set up the settings dir base to be \\path\to |
|
| 139 * The actual settings dir will be \\path\to\.purple */ |
|
| 140 char settingsdir[strlen(path) + strlen("PURPLEHOME=") + 1]; |
|
| 141 char aspelldir[strlen(path) + strlen("PIDGIN_ASPELL_DIR=\\Aspell\\bin") + 1]; |
|
| 142 |
|
| 143 snprintf(settingsdir, sizeof(settingsdir), "PURPLEHOME=%s", path); |
|
| 144 printf("Setting settings dir: %s\n", settingsdir); |
|
| 145 putenv(settingsdir); |
|
| 146 |
|
| 147 snprintf(aspelldir, sizeof(aspelldir), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path); |
|
| 148 printf("%s\n", aspelldir); |
|
| 149 putenv(aspelldir); |
|
| 150 |
|
| 151 /* set the GTK+ path to be \\path\to\GTK\bin */ |
|
| 152 strcat(path, "\\GTK\\bin"); |
|
| 153 } else |
|
| 154 return; |
|
| 155 #else /* PORTABLE */ |
|
| 156 char gtkpath[MAX_PATH + 1]; |
|
| 157 DWORD plen; |
|
| 158 |
|
| 159 plen = sizeof(gtkpath); |
|
| 160 hkey = HKEY_CURRENT_USER; |
|
| 161 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", |
|
| 162 (LPBYTE) >kpath, &plen)) { |
|
| 163 hkey = HKEY_LOCAL_MACHINE; |
|
| 164 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", |
|
| 165 (LPBYTE) >kpath, &plen)) { |
|
| 166 printf("GTK+ Path Registry Key not found. " |
|
| 167 "Assuming GTK+ is in the PATH.\n"); |
|
| 168 return; |
|
| 169 } |
|
| 170 } |
|
| 171 |
|
| 172 /* this value is replaced during a successful RegQueryValueEx() */ |
|
| 173 plen = sizeof(path); |
|
| 174 /* Determine GTK+ dll path .. */ |
|
| 175 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "DllPath", |
|
| 176 (LPBYTE) &path, &plen)) { |
|
| 177 strcpy(path, gtkpath); |
|
| 178 strcat(path, "\\bin"); |
|
| 179 } |
|
| 180 #endif |
|
| 181 printf("GTK+ path found: %s\n", path); |
115 printf("GTK+ path found: %s\n", path); |
| 182 |
116 |
| 183 if ((hmod = GetModuleHandle("kernel32.dll"))) { |
117 if ((hmod = GetModuleHandle("kernel32.dll"))) { |
| 184 MySetDllDirectory = (LPFNSETDLLDIRECTORY) GetProcAddress( |
118 MySetDllDirectory = (LPFNSETDLLDIRECTORY) GetProcAddress( |
| 185 hmod, "SetDllDirectoryA"); |
119 hmod, "SetDllDirectoryA"); |
| 245 (UINT) GetLastError()); |
179 (UINT) GetLastError()); |
| 246 } else |
180 } else |
| 247 printf("SafeDllSearchMode is set to 0\n"); |
181 printf("SafeDllSearchMode is set to 0\n"); |
| 248 }/*end else*/ |
182 }/*end else*/ |
| 249 } |
183 } |
| |
184 } |
| |
185 |
| |
186 static void portable_mode_dll_prep(const char *pidgin_dir) { |
| |
187 /* need to be able to fit MAX_PATH + "PIDGIN_ASPELL_DIR=\\Aspell\\bin" in path2 */ |
| |
188 char path[MAX_PATH + 1]; |
| |
189 char path2[MAX_PATH + 33]; |
| |
190 const char *prev = NULL; |
| |
191 |
| |
192 /* We assume that GTK+ is installed under \\path\to\Pidgin\..\GTK |
| |
193 * First we find \\path\to |
| |
194 */ |
| |
195 if (*pidgin_dir) { |
| |
196 /* pidgin_dir points to \\path\to\Pidgin */ |
| |
197 const char *tmp = pidgin_dir; |
| |
198 |
| |
199 while ((tmp = strchr(tmp, '\\'))) { |
| |
200 prev = tmp; |
| |
201 tmp++; |
| |
202 } |
| |
203 } |
| |
204 |
| |
205 if (prev) { |
| |
206 int cnt = (prev - pidgin_dir); |
| |
207 strncpy(path, pidgin_dir, cnt); |
| |
208 path[cnt] = '\0'; |
| |
209 } else { |
| |
210 printf("Unable to determine current executable path. \n" |
| |
211 "This will prevent the settings dir from being set.\n" |
| |
212 "Assuming GTK+ is in the PATH.\n"); |
| |
213 return; |
| |
214 } |
| |
215 |
| |
216 |
| |
217 /* Set up the settings dir base to be \\path\to |
| |
218 * The actual settings dir will be \\path\to\.purple */ |
| |
219 snprintf(path2, sizeof(path2), "PURPLEHOME=%s", path); |
| |
220 printf("Setting settings dir: %s\n", path2); |
| |
221 putenv(path2); |
| |
222 |
| |
223 snprintf(path2, sizeof(path2), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path); |
| |
224 printf("%s\n", path2); |
| |
225 putenv(path2); |
| |
226 |
| |
227 /* set the GTK+ path to be \\path\to\GTK\bin */ |
| |
228 strcat(path, "\\GTK\\bin"); |
| |
229 |
| |
230 common_dll_prep(path); |
| |
231 } |
| |
232 |
| |
233 static void dll_prep() { |
| |
234 char path[MAX_PATH + 1]; |
| |
235 HKEY hkey; |
| |
236 char gtkpath[MAX_PATH + 1]; |
| |
237 DWORD plen; |
| |
238 |
| |
239 plen = sizeof(gtkpath); |
| |
240 hkey = HKEY_CURRENT_USER; |
| |
241 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", |
| |
242 (LPBYTE) >kpath, &plen)) { |
| |
243 hkey = HKEY_LOCAL_MACHINE; |
| |
244 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", |
| |
245 (LPBYTE) >kpath, &plen)) { |
| |
246 printf("GTK+ Path Registry Key not found. " |
| |
247 "Assuming GTK+ is in the PATH.\n"); |
| |
248 return; |
| |
249 } |
| |
250 } |
| |
251 |
| |
252 /* this value is replaced during a successful RegQueryValueEx() */ |
| |
253 plen = sizeof(path); |
| |
254 /* Determine GTK+ dll path .. */ |
| |
255 if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "DllPath", |
| |
256 (LPBYTE) &path, &plen)) { |
| |
257 strcpy(path, gtkpath); |
| |
258 strcat(path, "\\bin"); |
| |
259 } |
| |
260 |
| |
261 common_dll_prep(path); |
| 250 } |
262 } |
| 251 |
263 |
| 252 static char* winpidgin_lcid_to_posix(LCID lcid) { |
264 static char* winpidgin_lcid_to_posix(LCID lcid) { |
| 253 char *posix = NULL; |
265 char *posix = NULL; |
| 254 int lang_id = PRIMARYLANGID(lcid); |
266 int lang_id = PRIMARYLANGID(lcid); |
| 396 - Use default user locale |
408 - Use default user locale |
| 397 */ |
409 */ |
| 398 static const char *winpidgin_get_locale() { |
410 static const char *winpidgin_get_locale() { |
| 399 const char *locale = NULL; |
411 const char *locale = NULL; |
| 400 LCID lcid; |
412 LCID lcid; |
| 401 #ifndef PORTABLE |
|
| 402 char data[10]; |
413 char data[10]; |
| 403 DWORD datalen = 10; |
414 DWORD datalen = 10; |
| 404 #endif |
|
| 405 |
415 |
| 406 /* Check if user set PIDGINLANG env var */ |
416 /* Check if user set PIDGINLANG env var */ |
| 407 if ((locale = getenv("PIDGINLANG"))) |
417 if ((locale = getenv("PIDGINLANG"))) |
| 408 return locale; |
418 return locale; |
| 409 |
419 |
| 410 #ifndef PORTABLE |
420 if (!portable_mode && read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\pidgin", |
| 411 if (read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\pidgin", |
|
| 412 "Installer Language", (LPBYTE) &data, &datalen)) { |
421 "Installer Language", (LPBYTE) &data, &datalen)) { |
| 413 if ((locale = winpidgin_lcid_to_posix(atoi(data)))) |
422 if ((locale = winpidgin_lcid_to_posix(atoi(data)))) |
| 414 return locale; |
423 return locale; |
| 415 } |
424 } |
| 416 #endif |
|
| 417 |
425 |
| 418 lcid = GetUserDefaultLCID(); |
426 lcid = GetUserDefaultLCID(); |
| 419 if ((locale = winpidgin_lcid_to_posix(lcid))) |
427 if ((locale = winpidgin_lcid_to_posix(lcid))) |
| 420 return locale; |
428 return locale; |
| 421 |
429 |
| 523 |
531 |
| 524 int _stdcall |
532 int _stdcall |
| 525 WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance, |
533 WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance, |
| 526 char *lpszCmdLine, int nCmdShow) { |
534 char *lpszCmdLine, int nCmdShow) { |
| 527 char errbuf[512]; |
535 char errbuf[512]; |
| 528 char pidgindir[MAX_PATH]; |
536 char pidgin_dir[MAX_PATH]; |
| |
537 char exe_name[MAX_PATH]; |
| 529 HMODULE hmod; |
538 HMODULE hmod; |
| 530 char *tmp; |
539 char *tmp; |
| 531 |
540 |
| 532 /* If debug or help or version flag used, create console for output */ |
541 /* If debug or help or version flag used, create console for output */ |
| 533 if (strstr(lpszCmdLine, "-d") || strstr(lpszCmdLine, "-h") || strstr(lpszCmdLine, "-v")) { |
542 if (strstr(lpszCmdLine, "-d") || strstr(lpszCmdLine, "-h") || strstr(lpszCmdLine, "-v")) { |
| 553 handle_protocol(tmp); |
562 handle_protocol(tmp); |
| 554 return 0; |
563 return 0; |
| 555 } |
564 } |
| 556 |
565 |
| 557 /* Load exception handler if we have it */ |
566 /* Load exception handler if we have it */ |
| 558 if (GetModuleFileName(NULL, pidgindir, MAX_PATH) != 0) { |
567 if (GetModuleFileName(NULL, pidgin_dir, MAX_PATH) != 0) { |
| 559 char *prev = NULL; |
568 char *prev = NULL; |
| 560 tmp = pidgindir; |
569 tmp = pidgin_dir; |
| 561 |
570 |
| |
571 /* primitive dirname() */ |
| 562 while ((tmp = strchr(tmp, '\\'))) { |
572 while ((tmp = strchr(tmp, '\\'))) { |
| 563 prev = tmp; |
573 prev = tmp; |
| 564 tmp++; |
574 tmp++; |
| 565 } |
575 } |
| 566 |
576 |
| 567 if (prev) { |
577 if (prev) { |
| 568 prev[0] = '\0'; |
578 prev[0] = '\0'; |
| 569 strcat(pidgindir, "\\exchndl.dll"); |
579 |
| 570 if (LoadLibrary(pidgindir)) |
580 /* prev++ will now point to the executable file name */ |
| |
581 strcpy(exe_name, prev + 1); |
| |
582 |
| |
583 strcat(pidgin_dir, "\\exchndl.dll"); |
| |
584 if (LoadLibrary(pidgin_dir)) |
| 571 printf("Loaded exchndl.dll\n"); |
585 printf("Loaded exchndl.dll\n"); |
| |
586 |
| |
587 prev[0] = '\0'; |
| 572 } |
588 } |
| 573 } else { |
589 } else { |
| 574 DWORD dw = GetLastError(); |
590 DWORD dw = GetLastError(); |
| 575 const char *err_msg = get_win32_error_message(dw); |
591 const char *err_msg = get_win32_error_message(dw); |
| 576 snprintf(errbuf, 512, |
592 snprintf(errbuf, 512, |
| 577 "Error getting module filename.\nError: (%u) %s", |
593 "Error getting module filename.\nError: (%u) %s", |
| 578 (UINT) dw, err_msg); |
594 (UINT) dw, err_msg); |
| 579 printf("%s", errbuf); |
595 printf("%s", errbuf); |
| 580 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); |
596 MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); |
| 581 } |
597 pidgin_dir[0] = '\0'; |
| 582 |
598 } |
| 583 #ifndef PORTABLE |
599 |
| 584 if (!getenv("PIDGIN_NO_DLL_CHECK")) |
600 /* Determine if we're running in portable mode */ |
| 585 #endif |
601 if (strstr(lpszCmdLine, "--portable-mode") |
| |
602 || (exe_name != NULL && strstr(exe_name, "-portable.exe"))) { |
| |
603 printf("Running in PORTABLE mode.\n"); |
| |
604 portable_mode = TRUE; |
| |
605 } |
| |
606 |
| |
607 if (portable_mode) |
| |
608 portable_mode_dll_prep(pidgin_dir); |
| |
609 else if (!getenv("PIDGIN_NO_DLL_CHECK")) |
| 586 dll_prep(); |
610 dll_prep(); |
| 587 |
611 |
| 588 winpidgin_set_locale(); |
612 winpidgin_set_locale(); |
| 589 /* If help, version or multiple flag used, do not check Mutex */ |
613 /* If help, version or multiple flag used, do not check Mutex */ |
| 590 if (!strstr(lpszCmdLine, "-h") && !strstr(lpszCmdLine, "-v") && !strstr(lpszCmdLine, "-m")) |
614 if (!strstr(lpszCmdLine, "-h") && !strstr(lpszCmdLine, "-v") && !strstr(lpszCmdLine, "-m")) |
| 591 if (!getenv("PIDGIN_MULTI_INST") && !winpidgin_set_running()) |
615 if (!getenv("PIDGIN_MULTI_INST") && !winpidgin_set_running()) |
| 592 return 0; |
616 return 0; |
| 593 |
617 |
| 594 /* Now we are ready for Pidgin .. */ |
618 /* Now we are ready for Pidgin .. */ |
| 595 if ((hmod = LoadLibrary("pidgin.dll"))) { |
619 if ((hmod = LoadLibrary("pidgin.dll"))) |
| 596 pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main"); |
620 pidgin_main = (LPFNPIDGINMAIN) GetProcAddress(hmod, "pidgin_main"); |
| 597 } |
|
| 598 |
621 |
| 599 if (!pidgin_main) { |
622 if (!pidgin_main) { |
| 600 DWORD dw = GetLastError(); |
623 DWORD dw = GetLastError(); |
| 601 BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND); |
624 BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND); |
| 602 const char *err_msg = get_win32_error_message(dw); |
625 const char *err_msg = get_win32_error_message(dw); |