2

One of my softwares need to change system proxies on Windows. Changing the HTTP proxy for LAN connections behind a router is easy, but I cannot find any information on how to change proxies for dialup or direct DSL (i.e. PPPoE) connections.

This is bad because a significant fraction of my clients are in China. In China, many people do not have more than one computer, and thus find a router wasteful. They simply connect their ADSL modem to their ethernet port and use PPPoE. Yes, this sucks for security and everything (one reason why botnets roam so freely in China) but it is reality and my software needs to work.

I also need code that gives me the list of all network connections. Just having code as in my related question that requires one to know the connection to edit would not work.

I also prefer something that would work by using the reg command. Simple C++ or C# code using the Windows API is also useful, but note that I'm using Racket, a language with a rather cumbersome FFI, which means that it would be best to minimize use of the Windows C API.

Community
  • 1
  • 1
ithisa
  • 752
  • 1
  • 8
  • 25

2 Answers2

6

Assuming you are unable to use Windows native API calls, I’ll put my bit by providing a solution that only would require calls to Windows commands (reg) and array/strings manipulation, something that the "Racket" language must implement for sure.

This is not the cleanest way but given the requirements it should be a feasible solution for you.

Well, as you perhaps have noticed, the proxy configuration for the different connections is stored under the key: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections

Under that key there’s a value that stores the DefaultConnectionSettings and another value that stores the SavedLegacySettings (both of type REG_BINARY). In addition to the two mentioned values there’s a value per each system connection (also of type REG_BINARY) that stores the connection configuration including the proxy settings. The name of the values equals the connection names.

Fortunately some guy have reverse engineered the structure of the BINARY data stored in those values.

  1. Byte number zero always has a 3C or 46 - I couldn't find more information about this byte.The next three bytes are zeros.
  2. Byte number 4 is a counter used by the 'Internet Options' property sheet (Internet explorer->Tools->Internet Options...). As you manually change the internet setting (such as LAN settings in the Connections tab), this counter increments.Its not very useful byte.But it MUST have a value. I keep it zero always. The next three bytes are zeros (Bytes 5 to 7).
  3. Byte number 8 can take different values as per your settings. The value is :
    • 09 when only 'Automatically detect settings' is enabled
    • 03 when only 'Use a proxy server for your LAN' is enabled
    • 0B when both are enabled
    • 05 when only 'Use automatic configuration script' is enabled
    • 0D when 'Automatically detect settings' and 'Use automatic configuration script' are enabled
    • 07 when 'Use a proxy server for your LAN' and 'Use automatic configuration script' are enabled
    • 0F when all the three are enabled.
    • 01 when none of them are enabled. The next three bytes are zeros (Bytes 9 to B).
  4. Byte number C (12 in decimal) contains the length of the proxy server address.For example a proxy server '127.0.0.1:80' has length 12 (length includes the dots and the colon).The next three bytes are zeros (Bytes D to F).
  5. Byte 10 (or 16 in decimal) contains the proxy server address - like '127.0.0.1:80' (where 80 is obviously the port number)
  6. The byte immediatley after the address contians the length of additional information.The next three bytes are zeros. For example if the 'Bypass proxy server for local addresses' is ticked, then this byte is 07,the next three bytes are zeros and then comes a string i.e. '' ( indicates that you are bypassing the proxy server.Now since has 7 characters, the length is 07!). You will have to experiment on your own for finding more about this. If you dont have any additional info then the length is 0 and no information is added.
  7. The byte immediately after the additional info, is the length of the automatic configuration script address (If you dont have a script address then you dont need to add anything,skip this step and goto step 8).The next three bytes are zeros,then comes the address.
  8. Finally, 32 zeros are appended.(I dont know why! Presumably to fill the binary blob, perhaps it is expected to be a certain length by something, don't you wish windows had some source?)

Complete info can be found here.

With this info I think you can manage to obtain the values in. Just do reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", properly parse the output and use reg again to write back the modifications.

I hope this helps.

TheMisir
  • 4,083
  • 1
  • 27
  • 37
mhcuervo
  • 2,610
  • 22
  • 33
  • I *can* do API calls, just not a whole ton of them. I need to do an API call in the end to set the InternetOptionsChanged constant anyways, otherwise IE doesn't listen. – ithisa Sep 12 '13 at 10:09
0

You may use this c# code to change proxy server for VPN connections:

// host looks like "127.0.0.1:8080"
public static void EnableVPNProxy(string host)
{
    RegistryKey RegKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", true);
    foreach (var name in RegKey.GetValueNames())
    {
        try
        {
            byte[] server = Encoding.ASCII.GetBytes(host);
            byte[] current = (byte[])RegKey.GetValue(name);
            byte[] data = new byte[100];

            data[0] = current[0];
            data[1] = data[2] = data[3] = data[4] = data[5] = data[6] = data[7] = 0;
            data[8] = 3;
            data[9] = data[10] = data[11] = 0;
            data[12] = Convert.ToByte(server.Length);
            data[13] = data[14] = data[15] = 0;

            int i = 16;

            foreach (var b in server)
            {
                data[i] = b;
                i++;
            }
            for (var x = 0; x < 40; x++)
            {
                data[i] = 0;
                i++;
            }
           RegKey.SetValue(name, data);
        }
        catch (Exception ex) { }
    }
}

And enable proxy

EnableVPNProxy("127.0.0.1:8080");
TheMisir
  • 4,083
  • 1
  • 27
  • 37