// // NCSWinHttpCloseHandle: wrapper around WinHttpCloseHandle // BOOL NCSWinHttpCloseHandle(LPVOID hInternet) { if (pWinHttpCloseHandle) { return pWinHttpCloseHandle((HINTERNET)hInternet); } else { return FALSE; } }
// Detect any proxy configuration settings automatically. static void windows_detect_autoproxy_settings() { if (log_flags.proxy_debug) { post_sysmon_msg("[proxy] automatic proxy check in progress"); } HMODULE hModWinHttp = LoadLibrary("winhttp.dll"); if (!hModWinHttp) { return; } pfnWinHttpOpen pWinHttpOpen = (pfnWinHttpOpen)GetProcAddress(hModWinHttp, "WinHttpOpen"); if (!pWinHttpOpen) { return; } pfnWinHttpCloseHandle pWinHttpCloseHandle = (pfnWinHttpCloseHandle)(GetProcAddress(hModWinHttp, "WinHttpCloseHandle")); if (!pWinHttpCloseHandle) { return; } pfnWinHttpGetProxyForUrl pWinHttpGetProxyForUrl = (pfnWinHttpGetProxyForUrl)(GetProcAddress(hModWinHttp, "WinHttpGetProxyForUrl")); if (!pWinHttpGetProxyForUrl) { return; } HINTERNET hWinHttp = NULL; WINHTTP_AUTOPROXY_OPTIONS autoproxy_options; WINHTTP_PROXY_INFO proxy_info; PARSED_URL purl; std::wstring network_test_url; size_t pos; memset(&autoproxy_options, 0, sizeof(autoproxy_options)); memset(&proxy_info, 0, sizeof(proxy_info)); autoproxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoproxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; autoproxy_options.fAutoLogonIfChallenged = TRUE; network_test_url = A2W(config.network_test_url).c_str(); hWinHttp = pWinHttpOpen( L"BOINC client", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL ); char msg[1024], buf[1024]; strcpy(msg, "[proxy] "); if (pWinHttpGetProxyForUrl(hWinHttp, network_test_url.c_str(), &autoproxy_options, &proxy_info)) { // Apparently there are some conditions where WinHttpGetProxyForUrl can return // success but where proxy_info.lpszProxy is null. Maybe related to UPNP? // // For the time being check to see if proxy_info.lpszProxy is non-null. // if (proxy_info.lpszProxy) { std::string proxy(W2A(std::wstring(proxy_info.lpszProxy))); std::string new_proxy; if (log_flags.proxy_debug) { strcat(msg, "proxy list: "); strcat(msg, proxy.c_str()); } if (!proxy.empty()) { // Trim string if more than one proxy is defined // proxy list is defined as: // ([<scheme>=][<scheme>"://"]<server>[":"<port>]) // Find and erase first delimeter type. pos = proxy.find(';'); if (pos != -1 ) { new_proxy = proxy.erase(pos); proxy = new_proxy; } // Find and erase second delimeter type. pos = proxy.find(' '); if (pos != -1 ) { new_proxy = proxy.erase(pos); proxy = new_proxy; } // Parse the remaining url parse_url(proxy.c_str(), purl); // Store the results for future use. if (0 != strcmp(working_proxy_info.autodetect_server_name, purl.host)) { // Reset clients connection error detection path net_status.need_physical_connection = false; working_proxy_info.autodetect_protocol = purl.protocol; safe_strcpy(working_proxy_info.autodetect_server_name, purl.host); working_proxy_info.autodetect_port = purl.port; } if (log_flags.proxy_debug) { sprintf(buf, "proxy detected %s:%d", purl.host, purl.port); strcat(msg, buf); } } } // Clean up if (proxy_info.lpszProxy) GlobalFree(proxy_info.lpszProxy); if (proxy_info.lpszProxyBypass) GlobalFree(proxy_info.lpszProxyBypass); } else { // We can get here if the user is switching from a network that // requires a proxy to one that does not require a proxy. working_proxy_info.autodetect_protocol = 0; strcpy(working_proxy_info.autodetect_server_name, ""); working_proxy_info.autodetect_port = 0; if (log_flags.proxy_debug) { strcat(msg, "no automatic proxy detected"); } } if (hWinHttp) pWinHttpCloseHandle(hWinHttp); FreeLibrary(hModWinHttp); if (log_flags.proxy_debug) { post_sysmon_msg(msg); } }