I have the following code:
#ifndef UNICODE#define UNICODE#endif#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0A00#endif#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN#endif#include <windows.h>#include <winhttp.h>#include <string>#include <iostream>#pragma comment(lib, "winhttp.lib")int wmain(int argc, wchar_t* argv[]) { if (argc != 2) { std::wcerr << L"Parameters: <Domain>" << std::endl; return 1; } // Get proxy settings WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxyConfig; ZeroMemory(&ProxyConfig, sizeof(ProxyConfig)); if (!WinHttpGetIEProxyConfigForCurrentUser(&ProxyConfig)) { std::wcerr << L"WinHttpGetIEProxyConfigForCurrentUser failed, error: "<< GetLastError() << std::endl; return 1; } if (ProxyConfig.lpszProxy != NULL) { // Check bypass list if (ProxyConfig.lpszProxyBypass != NULL) { wchar_t* domain = wcstok(ProxyConfig.lpszProxyBypass, L";"); while (domain != NULL) { if (wcscmp(domain, argv[1]) == 0) { std::wcout << L"Proxy Bypass" << std::endl; GlobalFree(ProxyConfig.lpszProxy); GlobalFree(ProxyConfig.lpszProxyBypass); return 0; } domain = wcstok(NULL, L";"); } GlobalFree(ProxyConfig.lpszProxyBypass); } std::wcout << L"Proxy: " << ProxyConfig.lpszProxy << std::endl; GlobalFree(ProxyConfig.lpszProxy); return 0; } // Set AUTOPROXY options WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions; ZeroMemory(&AutoProxyOptions, sizeof(AutoProxyOptions)); if (ProxyConfig.fAutoDetect) { AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; AutoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; } if (ProxyConfig.lpszAutoConfigUrl != NULL) { AutoProxyOptions.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; AutoProxyOptions.lpszAutoConfigUrl = ProxyConfig.lpszAutoConfigUrl; } if (AutoProxyOptions.dwFlags == NULL) { std::wcout << L"No Proxy" << std::endl; return 0; } AutoProxyOptions.fAutoLogonIfChallenged = TRUE; // Create WinHTTP session HINTERNET hSession = WinHttpOpen( L"Windows", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 ); if (hSession == NULL) { std::wcerr << L"WinHttpOpen failed, error: "<< GetLastError() << std::endl; return 1; } // Get proxy info from PAC std::wstring wurl = L"http://" + (std::wstring)argv[1] + L"/"; WINHTTP_PROXY_INFO ProxyInfo; ZeroMemory(&ProxyInfo, sizeof(ProxyInfo)); if (!WinHttpGetProxyForUrl( hSession, wurl.c_str(),&AutoProxyOptions,&ProxyInfo )) { std::wcerr << L"WinHttpGetProxyForUrl failed, error: "<< GetLastError() << std::endl; WinHttpCloseHandle(hSession); return 1; } // ProxyInfo.lpszProxy contains the address of the proxy server if (ProxyInfo.lpszProxy != NULL) { std::wcout << L"Proxy: " << ProxyInfo.lpszProxy << std::endl; GlobalFree(ProxyInfo.lpszProxy); } else { std::wcout << L"Proxy: NULL" << std::endl; } // Cleanup if (ProxyConfig.lpszAutoConfigUrl != NULL) { GlobalFree(ProxyConfig.lpszAutoConfigUrl); } WinHttpCloseHandle(hSession); return 0;}
It uses the WinHttpGetProxyForUrl
function to retrieve the proxy server address specified in the PAC file based on system settings.
The WinHttpGetProxyForUrl
function executed successfully without returning an error, but the given ProxyInfo.lpszProxy
variable value is always null.
The following is the content of the original PAC file I used:
var pHost = "Proxy.local";var pPort = "1080";var Socks5 = "SOCKS5 " + pHost +":" + pPort +"; ";var Socks = "SOCKS " + pHost +":" + pPort +"; ";var Direct = "DIRECT; ";function FindProxyForURL(url, host) { if (shExpMatch(dnsResolveEx(host), "*.*.*.*")) { return Socks5 + Socks + Direct; } else { return Direct; }}
The following is a simplified version of the PAC file that always returns a proxy server:
function FindProxyForURL(url, host) { return "SOCKS Proxy.local:1080";}
I have tried both, but the ProxyInfo.lpszProxy
variable still gets null.
Is there an issue with my code or is the WinHttpGetProxyForUrl
function exhibiting unexpected behavior?