Mercurial > pidgin.yaz
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, ®_key); |
333 if(RegOpenKeyExW(rootkey, wc_subkey, 0, | |
334 KEY_QUERY_VALUE, ®_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, ®_key); |
362 KEY_QUERY_VALUE, ®_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 */ |