comparison libgaim/win32/win32dep.c @ 14971:721465a37d4e

[gaim-migrate @ 17749] Re-read Windows proxy information when it has changed. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 15 Nov 2006 06:00:51 +0000
parents 650dee386bf6
children
comparison
equal deleted inserted replaced
14970:43f692951d49 14971:721465a37d4e
42 /* 42 /*
43 * DEFINES & MACROS 43 * DEFINES & MACROS
44 */ 44 */
45 #define _(x) gettext(x) 45 #define _(x) gettext(x)
46 46
47 #define WIN32_PROXY_REGKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
48
47 /* For shfolder.dll */ 49 /* For shfolder.dll */
48 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR); 50 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR);
49 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR); 51 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR);
50 52
51 /* 53 /*
53 */ 55 */
54 static char *app_data_dir = NULL, *install_dir = NULL, 56 static char *app_data_dir = NULL, *install_dir = NULL,
55 *lib_dir = NULL, *locale_dir = NULL; 57 *lib_dir = NULL, *locale_dir = NULL;
56 58
57 static HINSTANCE libgaimdll_hInstance = 0; 59 static HINSTANCE libgaimdll_hInstance = 0;
60
61 static HANDLE proxy_change_event = NULL;
62 static HKEY proxy_regkey = NULL;
58 63
59 /* 64 /*
60 * PUBLIC CODE 65 * PUBLIC CODE
61 */ 66 */
62 67
317 RegCloseKey(reg_key); 322 RegCloseKey(reg_key);
318 323
319 return success; 324 return success;
320 } 325 }
321 326
322 char *wgaim_read_reg_string(HKEY rootkey, const char *subkey, const char *valname) { 327 static HKEY _reg_open_key(HKEY rootkey, const char *subkey, REGSAM access) {
323 328 HKEY reg_key = NULL;
324 DWORD type; 329 LONG rv;
325 DWORD nbytes;
326 HKEY reg_key;
327 char *result = NULL;
328 330
329 if(G_WIN32_HAVE_WIDECHAR_API()) { 331 if(G_WIN32_HAVE_WIDECHAR_API()) {
330 wchar_t *wc_subkey = g_utf8_to_utf16(subkey, -1, NULL, 332 wchar_t *wc_subkey = g_utf8_to_utf16(subkey, -1, NULL,
331 NULL, NULL); 333 NULL, NULL);
332 334 rv = RegOpenKeyExW(rootkey, wc_subkey, 0, access, &reg_key);
333 if(RegOpenKeyExW(rootkey, wc_subkey, 0,
334 KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS) {
335 wchar_t *wc_valname = NULL;
336 if (valname)
337 wc_valname = g_utf8_to_utf16(valname, -1,
338 NULL, NULL, NULL);
339
340 if(RegQueryValueExW(reg_key, wc_valname, 0, &type,
341 NULL, &nbytes) == ERROR_SUCCESS
342 && type == REG_SZ) {
343 wchar_t *wc_temp =
344 g_new(wchar_t, ((nbytes + 1) / sizeof(wchar_t)) + 1);
345
346 if(RegQueryValueExW(reg_key, wc_valname, 0,
347 &type, (LPBYTE) wc_temp,
348 &nbytes) == ERROR_SUCCESS) {
349 wc_temp[nbytes / sizeof(wchar_t)] = '\0';
350 result = g_utf16_to_utf8(wc_temp, -1,
351 NULL, NULL, NULL);
352 }
353 g_free(wc_temp);
354 }
355 g_free(wc_valname);
356 }
357 g_free(wc_subkey); 335 g_free(wc_subkey);
358 } else { 336 } else {
359 char *cp_subkey = g_locale_from_utf8(subkey, -1, NULL, 337 char *cp_subkey = g_locale_from_utf8(subkey, -1, NULL,
360 NULL, NULL); 338 NULL, NULL);
361 if(RegOpenKeyExA(rootkey, cp_subkey, 0, 339 rv = RegOpenKeyExA(rootkey, cp_subkey, 0, access, &reg_key);
362 KEY_QUERY_VALUE, &reg_key) == ERROR_SUCCESS) { 340 g_free(cp_subkey);
363 char *cp_valname = NULL; 341 }
364 if(valname) 342
365 cp_valname = g_locale_from_utf8(valname, -1, 343 if (rv != ERROR_SUCCESS) {
366 NULL, NULL, NULL); 344 char *errmsg = g_win32_error_message(rv);
367 345 gaim_debug_info("wgaim", "Could not open reg key '%s' subkey '%s'.\nMessage: (%ld) %s\n",
368 if(RegQueryValueExA(reg_key, cp_valname, 0, &type, 346 ((rootkey == HKEY_LOCAL_MACHINE) ? "HKLM" :
369 NULL, &nbytes) == ERROR_SUCCESS 347 (rootkey == HKEY_CURRENT_USER) ? "HKCU" :
370 && type == REG_SZ) { 348 (rootkey == HKEY_CLASSES_ROOT) ? "HKCR" : "???"),
371 char *cp_temp = g_malloc(nbytes + 1); 349 subkey, rv, errmsg);
372 350 g_free(errmsg);
373 if(RegQueryValueExA(reg_key, cp_valname, 0, 351 }
374 &type, cp_temp, 352
375 &nbytes) == ERROR_SUCCESS) { 353 return reg_key;
354 }
355
356 static gboolean _reg_read(HKEY reg_key, const char *valname, LPDWORD type, LPBYTE data, LPDWORD data_len) {
357 LONG rv;
358
359 if(G_WIN32_HAVE_WIDECHAR_API()) {
360 wchar_t *wc_valname = NULL;
361 if (valname)
362 wc_valname = g_utf8_to_utf16(valname, -1, NULL, NULL, NULL);
363 rv = RegQueryValueExW(reg_key, wc_valname, 0, type, data, data_len);
364 g_free(wc_valname);
365 } else {
366 char *cp_valname = NULL;
367 if(valname)
368 cp_valname = g_locale_from_utf8(valname, -1, NULL, NULL, NULL);
369 rv = RegQueryValueExA(reg_key, cp_valname, 0, type, data, data_len);
370 g_free(cp_valname);
371 }
372
373 if (rv != ERROR_SUCCESS) {
374 char *errmsg = g_win32_error_message(rv);
375 gaim_debug_info("wgaim", "Could not read from reg key value '%s'.\nMessage: (%ld) %s\n",
376 valname, rv, errmsg);
377 g_free(errmsg);
378 }
379
380 return (rv == ERROR_SUCCESS);
381 }
382
383 gboolean wgaim_read_reg_dword(HKEY rootkey, const char *subkey, const char *valname, LPDWORD result) {
384
385 DWORD type;
386 DWORD nbytes;
387 HKEY reg_key = _reg_open_key(rootkey, subkey, KEY_QUERY_VALUE);
388 gboolean success = FALSE;
389
390 if(reg_key) {
391 if(_reg_read(reg_key, valname, &type, (LPBYTE)result, &nbytes))
392 success = TRUE;
393 RegCloseKey(reg_key);
394 }
395
396 return success;
397 }
398
399 char *wgaim_read_reg_string(HKEY rootkey, const char *subkey, const char *valname) {
400
401 DWORD type;
402 DWORD nbytes;
403 HKEY reg_key = _reg_open_key(rootkey, subkey, KEY_QUERY_VALUE);
404 char *result = NULL;
405
406 if(reg_key) {
407 if(_reg_read(reg_key, valname, &type, NULL, &nbytes) && type == REG_SZ) {
408 LPBYTE data;
409 if(G_WIN32_HAVE_WIDECHAR_API())
410 data = (LPBYTE) g_new(wchar_t, ((nbytes + 1) / sizeof(wchar_t)) + 1);
411 else
412 data = (LPBYTE) g_malloc(nbytes + 1);
413
414 if(_reg_read(reg_key, valname, &type, data, &nbytes)) {
415 if(G_WIN32_HAVE_WIDECHAR_API()) {
416 wchar_t *wc_temp = (wchar_t*) data;
417 wc_temp[nbytes / sizeof(wchar_t)] = '\0';
418 result = g_utf16_to_utf8(wc_temp, -1,
419 NULL, NULL, NULL);
420 } else {
421 char *cp_temp = (char*) data;
376 cp_temp[nbytes] = '\0'; 422 cp_temp[nbytes] = '\0';
377 result = g_locale_to_utf8(cp_temp, -1, 423 result = g_locale_to_utf8(cp_temp, -1,
378 NULL, NULL, NULL); 424 NULL, NULL, NULL);
379 } 425 }
380 g_free (cp_temp);
381 } 426 }
382 g_free(cp_valname); 427 g_free(data);
383 } 428 }
384 g_free(cp_subkey);
385 }
386
387 if(reg_key != NULL)
388 RegCloseKey(reg_key); 429 RegCloseKey(reg_key);
430 }
389 431
390 return result; 432 return result;
433 }
434
435 static void wgaim_refresh_proxy(void) {
436 gboolean set_proxy = FALSE;
437 DWORD enabled = 0;
438
439 wgaim_read_reg_dword(HKEY_CURRENT_USER, WIN32_PROXY_REGKEY,
440 "ProxyEnable", &enabled);
441
442 if (enabled & 1) {
443 char *c = NULL;
444 char *tmp = wgaim_read_reg_string(HKEY_CURRENT_USER, WIN32_PROXY_REGKEY,
445 "ProxyServer");
446
447 /* There are proxy settings for several protocols */
448 if (tmp && (c = g_strstr_len(tmp, strlen(tmp), "http="))) {
449 char *d;
450 c += strlen("http=");
451 d = strchr(c, ';');
452 if (d)
453 *d = '\0';
454 /* c now points the proxy server (and port) */
455
456 /* There is only a global proxy */
457 } else if (tmp && strlen(tmp) > 0 && !strchr(tmp, ';')) {
458 c = tmp;
459 }
460
461 if (c) {
462 gaim_debug_info("wgaim", "Setting HTTP Proxy: 'http://%s'\n", c);
463 g_setenv("HTTP_PROXY", c, TRUE);
464 set_proxy = TRUE;
465 }
466 g_free(tmp);
467 }
468
469 /* If there previously was a proxy set and there isn't one now, clear it */
470 if (getenv("HTTP_PROXY") && !set_proxy) {
471 gaim_debug_info("wgaim", "Clearing HTTP Proxy\n");
472 g_unsetenv("HTTP_PROXY");
473 }
474 }
475
476 static void watch_for_proxy_changes(void) {
477 LONG rv;
478 DWORD filter = REG_NOTIFY_CHANGE_NAME |
479 REG_NOTIFY_CHANGE_LAST_SET;
480
481 if (!proxy_regkey &&
482 !(proxy_regkey = _reg_open_key(HKEY_CURRENT_USER,
483 WIN32_PROXY_REGKEY, KEY_NOTIFY))) {
484 return;
485 }
486
487 if (!(proxy_change_event = CreateEvent(NULL, TRUE, FALSE, NULL))) {
488 char *errmsg = g_win32_error_message(GetLastError());
489 gaim_debug_error("wgaim", "Unable to watch for proxy changes: %s\n", errmsg);
490 g_free(errmsg);
491 return;
492 }
493
494 rv = RegNotifyChangeKeyValue(proxy_regkey, TRUE, filter, proxy_change_event, TRUE);
495 if (rv != ERROR_SUCCESS) {
496 char *errmsg = g_win32_error_message(rv);
497 gaim_debug_error("wgaim", "Unable to watch for proxy changes: %s\n", errmsg);
498 g_free(errmsg);
499 CloseHandle(proxy_change_event);
500 proxy_change_event = NULL;
501 }
502
503 }
504
505 gboolean wgaim_check_for_proxy_changes(void) {
506 gboolean changed = FALSE;
507
508 if (proxy_change_event && WaitForSingleObject(proxy_change_event, 0) == WAIT_OBJECT_0) {
509 CloseHandle(proxy_change_event);
510 proxy_change_event = NULL;
511 changed = TRUE;
512 wgaim_refresh_proxy();
513 watch_for_proxy_changes();
514 }
515
516 return changed;
391 } 517 }
392 518
393 void wgaim_init(void) { 519 void wgaim_init(void) {
394 WORD wVersionRequested; 520 WORD wVersionRequested;
395 WSADATA wsaData; 521 WSADATA wsaData;
428 g_free(newenv); 554 g_free(newenv);
429 555
430 if (!g_thread_supported()) 556 if (!g_thread_supported())
431 g_thread_init(NULL); 557 g_thread_init(NULL);
432 558
559 /* If the proxy server environment variables are already set,
560 * we shouldn't override them */
561 if (!getenv("HTTP_PROXY") && !getenv("http_proxy") && !getenv("HTTPPROXY")) {
562 wgaim_refresh_proxy();
563 watch_for_proxy_changes();
564 } else {
565 gaim_debug_info("wgaim", "HTTP_PROXY env. var already set. Ignoring win32 Internet Settings.\n");
566 }
567
433 gaim_debug_info("wgaim", "wgaim_init end\n"); 568 gaim_debug_info("wgaim", "wgaim_init end\n");
434 } 569 }
435 570
436 /* Windows Cleanup */ 571 /* Windows Cleanup */
437 572
441 /* winsock cleanup */ 576 /* winsock cleanup */
442 WSACleanup(); 577 WSACleanup();
443 578
444 g_free(app_data_dir); 579 g_free(app_data_dir);
445 app_data_dir = NULL; 580 app_data_dir = NULL;
581
582 if (proxy_regkey) {
583 RegCloseKey(proxy_regkey);
584 proxy_regkey = NULL;
585 }
446 586
447 libgaimdll_hInstance = NULL; 587 libgaimdll_hInstance = NULL;
448 } 588 }
449 589
450 /* DLL initializer */ 590 /* DLL initializer */