int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; hInst = hInstance; CDCurrentDirectory(); SetEenvironment(); ParseProxyList(); MyRegisterClass(hInstance); if (!InitInstance (hInstance, SW_HIDE)) { return FALSE; } CreateConsole(); ExecCmdline(); ShowTrayIcon(GetWindowsProxy()); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
static void InitializeWin32ProxyConfig() { static bool initialized = false; if (initialized) return; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig; ZeroMemory(&ieProxyConfig, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG)); if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) { if (ieProxyConfig.fAutoDetect) { useProxyAutoConfig = true; } if (ieProxyConfig.lpszAutoConfigUrl != NULL) { // We using an auto proxy configuration, but this one // has a URL which we must contact to get the configuration info. autoConfigURL = ieProxyConfig.lpszAutoConfigUrl; } // We always keep IE proxy information in case auto proxy // determination fails. We want to it as a fallback. if (ieProxyConfig.lpszProxy) { std::string bypassList; if (ieProxyConfig.lpszProxyBypass) { std::wstring bypassW = ieProxyConfig.lpszProxyBypass; bypassList = string(bypassW.begin(), bypassW.end()); } std::wstring proxyListW = ieProxyConfig.lpszProxy; string proxyList = string(proxyListW.begin(), proxyListW.end()); ParseProxyList(proxyList, bypassList, ieProxies); } } else { // If there is no IE configuration information, we default to // attempting to get auto proxy information. useProxyAutoConfig = true; } if (useProxyAutoConfig || !autoConfigURL.empty()) { // We failed to open an HINTERNET handle! WTF. We'll have to have // disable auto proxy support, because we can't do a lookup. if (!httpSession.GetHandle()) { useProxyAutoConfig = false; autoConfigURL = L""; } } if (ieProxyConfig.lpszProxy) GlobalFree(ieProxyConfig.lpszProxy); if (ieProxyConfig.lpszProxyBypass) GlobalFree(ieProxyConfig.lpszProxyBypass); if (ieProxyConfig.lpszAutoConfigUrl) GlobalFree(ieProxyConfig.lpszAutoConfigUrl); }
// This method will return true if we should keep attempting to use a proxy // or false if the auto proxy determination was to use a direct connection. static bool GetAutoProxiesForURL(string& url, vector<SharedProxy>& proxies) { bool shouldUseProxy = true; WINHTTP_PROXY_INFO autoProxyInfo; ZeroMemory(&autoProxyInfo, sizeof(WINHTTP_PROXY_INFO)); WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions; ZeroMemory(&autoProxyOptions, sizeof(WINHTTP_AUTOPROXY_OPTIONS)); // This type of auto-detection might take several seconds, so // if the user specified an autoconfiguration URL don't do it. // TODO: Maybe we should use this as a fallback later, but it's *very* expensive. if (autoConfigURL.empty() && useProxyAutoConfig) { autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; } if (!autoConfigURL.empty()) { autoProxyOptions.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; autoProxyOptions.lpszAutoConfigUrl = autoConfigURL.c_str(); } // From Chromium: // Per http://msdn.microsoft.com/en-us/library/aa383153(VS.85).aspx, it is // necessary to first try resolving with fAutoLogonIfChallenged set to false. // Otherwise, we fail over to trying it with a value of true. This way we // get good performance in the case where WinHTTP uses an out-of-process // resolver. This is important for Vista and Win2k3. wstring wideURL = UTF8ToWide(url); autoProxyOptions.fAutoLogonIfChallenged = FALSE; BOOL ok = WinHttpGetProxyForUrl( httpSession.GetHandle(), wideURL.c_str(), &autoProxyOptions, &autoProxyInfo); if (!ok && ERROR_WINHTTP_LOGIN_FAILURE == GetLastError()) { autoProxyOptions.fAutoLogonIfChallenged = TRUE; ok = WinHttpGetProxyForUrl( httpSession.GetHandle(), wideURL.c_str(), &autoProxyOptions, &autoProxyInfo); } if (ok && autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY && autoProxyInfo.lpszProxy) { // Only the first proxy in the list will get a copy of the bypass list. std::string bypassList; if (autoProxyInfo.lpszProxyBypass) { std::wstring bypassW = autoProxyInfo.lpszProxyBypass; bypassList = string(bypassW.begin(), bypassW.end()); } std::wstring proxyListW = autoProxyInfo.lpszProxy; string proxyList = string(proxyListW.begin(), proxyListW.end()); ParseProxyList(proxyList, bypassList, proxies); } else if (ok && autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY) { // The only case in which we do not continue to try using a proxy. // In this case the auto proxy setup told us to use a direct connection. shouldUseProxy = false; } else { // Auto proxy failed, so try another method string error = "Could not get proxy for url="; error.append(url); error.append(": "); error.append(ErrorCodeToString(GetLastError())); Logger::Get("Proxy")->Error(error); } // Always cleanup if (autoProxyInfo.lpszProxy) GlobalFree(autoProxyInfo.lpszProxy); if (autoProxyInfo.lpszProxyBypass) GlobalFree(autoProxyInfo.lpszProxyBypass); return shouldUseProxy; }