Click here to Skip to main content
Click here to Skip to main content
Go to top

Toggle Internet Proxy settings - an alternate approach

, 19 Feb 2003
Rate this:
Please Sign up or sign in to vote.
A code snippet for programmatically toggling IE proxy settings, while storing the previous state.

Introduction

I had the need to test a local (on the same machine I was using) Internet proxy. Every time I had to browse the network for info, I had to go reset Internet Explorer settings, or use a different browser. Since I did it for a customer with a totally different environment, I devised a small settings toggler, that just stores the previous values in the registry and can restore them. I made it a tray button, so a double-click was sufficient to set the proxy on and off.

There is another article "Change Internet Proxy settings" that deals with this topic. This article present an alternate method. 

Using the code

I just put the activate/deactivate functions and an initialize method for file-scope variables. It is quite easy to make them method of your class, and use them. Double activation or deactivation just do nothing.

const char *sKeyName, *sValName, *sAccName, *sFlgName, *sBypName;

void initialize( )
{
    sKeyName = "Software\\ProxyToggle";
    sValName = "SavedProxyConfig";
    sAccName = "AccessType";
    sFlgName = "ProxyActive";
    sBypName = "BypassList";
}

void activate( const char *address )
{
    // read config
    unsigned long        nSize = 4096;
    char                 szBuf[4096] = { 0 };

    // Read IE settings
    INTERNET_PROXY_INFO* pInfo = (INTERNET_PROXY_INFO*)szBuf;

    if(!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, pInfo, &nSize))
    {
       printf("InternetQueryOption failed! (%d)\n", GetLastError());
       exit( 100 );
    }
    // if necessary, store config
    const char *save = pInfo->lpszProxy;
    HKEY kValue;

    int res;
    BYTE Value[0x100];
    ULONG length = 0x100, Type;
    res = RegOpenKeyEx( HKEY_CURRENT_USER, sKeyName, 0, 
                        KEY_SET_VALUE | KEY_QUERY_VALUE, &kValue );
    if (res==ERROR_SUCCESS)
    {
        BYTE retVal = 0;
        if( ( res = RegQueryValueEx(kValue, sFlgName, NULL, 
                                    &Type, Value, &length) ) == ERROR_SUCCESS )
        {
            if( Type != REG_SZ )
            {
               printf("Corrupted registry entry\n" );
               exit( 400 );
            }
            retVal = *Value;
        }
        if( retVal )
        {
            RegCloseKey( kValue );
            return;
        }
    }
    else
        if( ( res = RegCreateKey( HKEY_CURRENT_USER, sKeyName, &kValue ) ) != ERROR_SUCCESS )
        {
           printf("Unable to save configuration\n" );
           exit( 600 );
        }

    *Value = 1;
    if( ( res = RegSetValueEx( kValue, sFlgName, 0, REG_SZ, 
                                    Value, sizeof( BYTE ) ) ) != ERROR_SUCCESS)
    {
       printf("Unable to update configuration\n" );
       exit( 500 );
    }
    if( ( res = RegSetValueEx( kValue, sAccName, 0, REG_SZ, (BYTE*)&(pInfo->dwAccessType), 
                               sizeof( DWORD ) ) ) != ERROR_SUCCESS)
    {
       printf("Unable to save configuration\n" );
       exit( 400 );
    }
    if( pInfo->dwAccessType != PROXY_TYPE_DIRECT )
    {
        if( ( res = RegSetValueEx( kValue, sValName, 0, REG_SZ, 
                                  (BYTE*)pInfo->lpszProxy, 1 + strlen( pInfo->lpszProxy ) ) ) 
            != ERROR_SUCCESS)
        {
           printf("Unable to save configuration\n" );
           exit( 400 );
        }
        if( ( res = RegSetValueEx( kValue, sBypName, 0, REG_SZ, 
                                  (BYTE*)pInfo->lpszProxyBypass, 
                                   1 + strlen( pInfo->lpszProxyBypass ) ) ) != ERROR_SUCCESS)
        {
           printf("Unable to save configuration\n" );
           exit( 400 );
        }
    }
    RegCloseKey( kValue );
    RegCloseKey( HKEY_CURRENT_USER );

    // Set IE settings

    INTERNET_PER_CONN_OPTION_LIST list;
    BOOL    bReturn;
    DWORD   dwBufSize = sizeof(list);

    // Fill out list struct.
    list.dwSize = sizeof(list);

    // NULL == LAN, otherwise connectoid name.
    list.pszConnection = NULL;

    // Set three options.
    list.dwOptionCount = 3;
    list.pOptions = new INTERNET_PER_CONN_OPTION[3];

    // Make sure the memory was allocated.
    if(NULL == list.pOptions)
    {
        //Return FALSE if the memory wasn't allocated.
        return;
    }

    // Set flags.
    list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
    list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT |
        PROXY_TYPE_PROXY;

    // Set proxy name.
    list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
    list.pOptions[1].Value.pszValue = (char*)address;

    // Add proxy name to bypass list.
    CString sAddr = address, bypass = pInfo->lpszProxyBypass;
    if( bypass.GetLength( ) )
        bypass += ";";
    int idx;
    if( ( idx = sAddr.Find( "//" ) ) >= 0 )
        sAddr = sAddr.Mid( idx + 2 );
    if( ( idx = sAddr.FindOneOf( ":/" ) ) >= 0 )
        sAddr = sAddr.Left( idx );
    bypass += sAddr;
    list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
    list.pOptions[2].Value.pszValue = bypass.GetBuffer( 0 );

    // Set the options on the connection.
    bReturn = InternetSetOption(NULL,
        INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);

    // Notify settings change.
    bReturn = InternetSetOption(NULL,
        INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0 );

    // Free the allocated memory.
    bypass.ReleaseBuffer( );
    delete [] list.pOptions;
}

void deactivate( )
{
    HKEY kValue;

    LONG res;
    BYTE Value[0x100], Bypass[0x100];
    ULONG length = 0x100, blength = 0x100, Type;
    unsigned long        nSize = 4096;
    char                 szBuf[4096] = { 0 };

    res = RegOpenKeyEx( HKEY_CURRENT_USER, sKeyName, 0, 
                        KEY_SET_VALUE | KEY_QUERY_VALUE, &kValue );
    if (res==ERROR_SUCCESS)
    {
        BYTE retVal = 0;
        if( ( res = RegQueryValueEx(kValue, sFlgName, NULL, 
                                    &Type, Value, &length) ) == ERROR_SUCCESS )
        {
            if( Type != REG_SZ )
            {
               printf("Corrupted registry entry\n" );
               exit( 400 );
            }
            retVal = *Value;
        }
        if( retVal )
        {
            *Value = 0;
            if( ( res = RegSetValueEx( kValue, sFlgName, 0, REG_SZ, Value, 
                                       sizeof( BYTE ) ) ) != ERROR_SUCCESS)
            {
               printf("Unable to update configuration\n" );
               exit( 500 );
            }

            INTERNET_PER_CONN_OPTION_LIST list;
            BOOL    bReturn;
            DWORD   dwBufSize = sizeof(list);

            // Fill out list struct.
            list.dwSize = sizeof(list);

            // NULL == LAN, otherwise connectoid name.
            list.pszConnection = NULL;

            // Set three options.
            list.dwOptionCount = 2;
            list.pOptions = new INTERNET_PER_CONN_OPTION[3];

            // Make sure the memory was allocated.
            if(NULL == list.pOptions)
            {
                //Return FALSE if the memory wasn't allocated.
                return;
            }

            // Set flags.
            list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
            
            length = sizeof( DWORD );
            if( ( res = RegQueryValueEx( kValue, sAccName, NULL, &Type, 
                                       (BYTE*)&(list.pOptions[0].Value.dwValue), &length ) ) 
                                              != ERROR_SUCCESS )
            {
               printf("Unable to restore configuration\n" );
               exit( 700 );
            }

            // Set proxy name and bypass.
            if( list.pOptions[0].Value.dwValue != PROXY_TYPE_DIRECT )
            {
                list.dwOptionCount = 3;
                length = 0x100;
                if( ( res = RegQueryValueEx( kValue, sValName, NULL, 
                                             &Type, Value, &length ) ) != ERROR_SUCCESS )
                {
                   printf("Unable to restore configuration\n" );
                   exit( 700 );
                }
                list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
                list.pOptions[1].Value.pszValue = (char*)Value;

                if( ( res = RegQueryValueEx( kValue, sBypName, NULL, 
                                          &Type, Bypass, &blength ) ) != ERROR_SUCCESS )
                {
                   printf("Unable to restore configuration\n" );
                   exit( 700 );
                }
                list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
                list.pOptions[2].Value.pszValue = (char*)Bypass;
            }

            // Set the options on the connection.
            bReturn = InternetSetOption(NULL,
                INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);

            // Notify settings change.
            bReturn = InternetSetOption(NULL,
                INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0 );

            // Free the allocated memory.
            delete [] list.pOptions;

            RegCloseKey( kValue );
        }
    }

    RegCloseKey( HKEY_CURRENT_USER );
}

Points of Interest

I noticed two things: the behavior was slightly different with different flavours of Windows until I met the last version of SDK. The whole thing is very poorly documented, as usual. After a lot of trial and error, now I have an intoxicated IE installation, that often hang while talking with proxy. So, DON'T MESS WITH THE REGISTRY. EVER.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Daniele Alberto Galliano
Software Developer (Senior) JRC
Italy Italy
No Biography provided

Comments and Discussions

 
QuestionDirectShow Support problem? PinmemberLittlePK22-Feb-03 19:55 
QuestionKey points? PinmemberR. Reyes20-Feb-03 23:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 20 Feb 2003
Article Copyright 2003 by Daniele Alberto Galliano
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid