c++windowswinapiproxysettings

How to read proxy settings


I am trying to read the proxy settings that are set in Windows. Let's say I have a string in my proxy settings http=127.0.0.1:2222;https=127.0.0.1:2222. I want to programmatically access (read) this string.

I tried to do this using the InternetQueryOption function, but it didn't work. Below I provide my code, which

  1. If proxying is disabled, it displays "No proxy server configured."
  2. If proxying is enabled, proxyInfo.lpszProxy contains an empty string

This is not the result I expect. I need to read a string from the proxy settings even if proxying is disabled.

#include <windows.h>
#include <wininet.h>
#include <iostream>
#pragma comment(lib, "wininet.lib")

void GetProxyServer()
{
    DWORD dwSize = 0;
    INTERNET_PROXY_INFO proxyInfo;

    if (InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &dwSize) || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
    {
        char* buffer = new char[dwSize];

        if (InternetQueryOption(NULL, INTERNET_OPTION_PROXY, buffer, &dwSize))
        {
            proxyInfo = *reinterpret_cast<INTERNET_PROXY_INFO*>(buffer);
            if (proxyInfo.lpszProxy)
            {
                std::wcout << "Proxy Server: " << proxyInfo.lpszProxy << std::endl;
            }
            else
            {
                std::cout << "No proxy server configured." << std::endl;
            }
        }
        else
        {
            std::cerr << "Error getting proxy information: " << GetLastError() << std::endl;
        }

        delete[] buffer;
    }
    else
    {
        std::cerr << "Error getting proxy size: " << GetLastError() << std::endl;
    }
}


int main() 
{
    GetProxyServer();
}

Solution

  • As @RemyLebeau suggested in the comments, you should use INTERNET_OPTION_PER_CONNECTION_OPTION. The full solution might look like this:

    #include <windows.h>
    #include <wininet.h>
    #include <iostream>
    
    #pragma comment(lib, "wininet.lib")
    
    int main() {
        INTERNET_PER_CONN_OPTION_LIST optionList;
        INTERNET_PER_CONN_OPTION options[3];
        unsigned long size = sizeof(optionList);
    
        optionList.dwSize = sizeof(optionList);
        optionList.pszConnection = NULL;
        optionList.dwOptionCount = 3;
        optionList.pOptions = options;
    
        options[0].dwOption = INTERNET_PER_CONN_FLAGS;
        options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
        options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
    
        if (!InternetQueryOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &optionList, &size)) {
            std::cout << "InternetQueryOption failed. Error: " << GetLastError() << std::endl;
            return 1;
        }
    
        std::cout << "Flags: " << optionList.pOptions[0].Value.dwValue << std::endl;
    
        if (optionList.pOptions[1].Value.pszValue)
            std::wcout << L"Proxy Server: " << optionList.pOptions[1].Value.pszValue << std::endl;
    
        if (optionList.pOptions[2].Value.pszValue)
            std::wcout << L"Proxy Bypass: " << optionList.pOptions[2].Value.pszValue << std::endl;
    
        if (optionList.pOptions[1].Value.pszValue)
            GlobalFree(optionList.pOptions[1].Value.pszValue);
        if (optionList.pOptions[2].Value.pszValue)
            GlobalFree(optionList.pOptions[2].Value.pszValue);
    
        return 0;
    }