View Single Post
 
Old 11-09-2016, 03:48 AM
charlie's Avatar
charlie charlie is offline
Senior Contributor
 
Join Date: Jul 2003
Location: Barcelona (SPAIN)
Posts: 1,057
Question Change system proxy (auto configuration file)

Hello.

I need to change the system proxy (IE proxy) and use a PAC file, not a proxy server.

I have this class I got from somewhere:

Code:
Option Strict On

Imports System.Runtime.InteropServices

Public Class IEProxy

    Public Enum Options
        INTERNET_PER_CONN_FLAGS = 1
        INTERNET_PER_CONN_PROXY_SERVER = 2
        INTERNET_PER_CONN_PROXY_BYPASS = 3
        INTERNET_PER_CONN_AUTOCONFIG_URL = 4
        INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5

        INTERNET_OPTION_REFRESH = 37
        INTERNET_OPTION_PROXY = 38
        INTERNET_OPTION_SETTINGS_CHANGED = 39
        INTERNET_OPTION_END_BROWSER_SESSION = 42
        INTERNET_OPTION_PER_CONNECTION_OPTION = 75

        PROXY_TYPE_DIRECT = &H1
        PROXY_TYPE_PROXY = &H2
        PROXY_TYPE_AUTO_PROXY_URL = &H4
        PROXY_TYPE_AUTO_DETECT = &H8
    End Enum


    <StructLayout(LayoutKind.Sequential)> Private Class FILETIME
        Public dwLowDateTime As Integer
        Public dwHighDateTime As Integer
    End Class


    <StructLayout(LayoutKind.Explicit, Size:=12)> Private Structure INTERNET_PER_CONN_OPTION

        <FieldOffset(0)> Dim dwOption As Integer
        <FieldOffset(4)> Dim dwValue As Integer
        <FieldOffset(4)> Dim pszValue As IntPtr
        <FieldOffset(4)> Dim ftValue As IntPtr

        Public Function GetBytes() As Byte()
            Dim b(12) As Byte
            BitConverter.GetBytes(dwOption).CopyTo(b, 0)
            Select Case dwOption
                Case (Options.INTERNET_PER_CONN_FLAGS)
                    BitConverter.GetBytes(dwValue).CopyTo(b, 4)
                Case (Options.INTERNET_PER_CONN_PROXY_BYPASS)
                    BitConverter.GetBytes(pszValue.ToInt32()).CopyTo(b, 4)
                Case (Options.INTERNET_PER_CONN_PROXY_SERVER)
                    BitConverter.GetBytes(pszValue.ToInt32()).CopyTo(b, 4)
            End Select
            Return (b)
        End Function

    End Structure


    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> Private Class INTERNET_PER_CONN_OPTION_LIST
        Public dwSize As Integer
        Public pszConnection As String
        Public dwOptionCount As Integer
        Public dwOptionError As Integer
        Public pOptions As IntPtr
    End Class


    <StructLayout(LayoutKind.Sequential)> Private Class INTERNET_PROXY_INFO
        Public dwAccessType As Integer
        Public lpszProxy As String 'IntPtr 
        Public lpszProxyBypass As String 'IntPtr 
    End Class


    Private Const ERROR_INSUFFICIENT_BUFFER = 122


    <DllImport("wininet.dll")> Private Shared Function InternetSetOption(ByVal hInternet As IntPtr, _
                                                                         ByVal dwOption As Integer, _
                                                                         ByVal lpBuffer As INTERNET_PER_CONN_OPTION_LIST, _
                                                                         ByVal dwBufferLength As Integer) As Boolean
    End Function


    <DllImport("kernel32.dll")> Private Shared Function GetLastError() As Integer
    End Function


    Public Function SetProxy(ByVal proxy_full_addr As String, ByVal Bypass As Boolean, ByVal PAC As Boolean) As Boolean
        Const NuM_OPCIONES As Integer = 3
        Dim bReturn As Boolean
        Dim list As New INTERNET_PER_CONN_OPTION_LIST
        Dim dwBufSize As Integer = Marshal.SizeOf(list)
        Dim opts(NuM_OPCIONES - 1) As INTERNET_PER_CONN_OPTION
        Dim opt_size As Integer = Marshal.SizeOf(opts(0))

        list.dwSize = dwBufSize
        list.pszConnection = ControlChars.NullChar
        list.dwOptionCount = NuM_OPCIONES

        ' Set flags -> OK.
        opts(0).dwOption = Options.INTERNET_PER_CONN_FLAGS
        If PAC Then
            opts(0).dwValue = Options.PROXY_TYPE_AUTO_PROXY_URL
        Else
            opts(0).dwValue = Options.PROXY_TYPE_PROXY
        End If

        ' Set Proxy Name -> KO.
        ' It works for proxy servers, not PAC files.
        If PAC Then
            opts(1).dwOption = Options.INTERNET_PER_CONN_AUTOCONFIG_URL
            opts(1).pszValue = Marshal.StringToHGlobalAnsi(proxy_full_addr) ' FAIL!
        Else
            opts(1).dwOption = Options.INTERNET_PER_CONN_PROXY_SERVER
            opts(1).pszValue = Marshal.StringToHGlobalAnsi(proxy_full_addr)
        End If

        ' Set override -> OK.
        opts(2).dwOption = Options.INTERNET_PER_CONN_PROXY_BYPASS
        If Bypass And Not PAC Then
            opts(2).pszValue = Marshal.StringToHGlobalAnsi("<local>")
        Else
            opts(2).pszValue = Marshal.StringToHGlobalAnsi("")
        End If

        Dim b(NuM_OPCIONES * opt_size) As Byte
        opts(0).GetBytes().CopyTo(b, 0)
        opts(1).GetBytes().CopyTo(b, opt_size)
        opts(2).GetBytes().CopyTo(b, (NuM_OPCIONES - 1) * opt_size)

        Dim ptr As IntPtr = Marshal.AllocCoTaskMem(list.dwOptionCount * opt_size)
        Marshal.Copy(b, 0, ptr, list.dwOptionCount * opt_size)

        list.pOptions = ptr

        ' Set the options on the connection.
        bReturn = InternetSetOption(IntPtr.Zero, Options.INTERNET_OPTION_PER_CONNECTION_OPTION, list, dwBufSize)
        If Not bReturn Then Debug.WriteLine(GetLastError)

        'Notify existing IE instances that the settings have changed.
        bReturn = InternetSetOption(IntPtr.Zero, Options.INTERNET_OPTION_SETTINGS_CHANGED, Nothing, 0)
        If Not bReturn Then Debug.WriteLine(GetLastError)

        ' Flush the current IE proxy setting.
        bReturn = InternetSetOption(IntPtr.Zero, Options.INTERNET_OPTION_REFRESH, Nothing, 0)
        If Not bReturn Then Debug.WriteLine(GetLastError)

        Marshal.FreeHGlobal(opts(1).pszValue)
        Marshal.FreeHGlobal(opts(2).pszValue)
        Marshal.FreeCoTaskMem(ptr)

        Return (bReturn)

    End Function

End Class
I tuned a bit the code from Internet and the function SetProxy() is working fine for everything except for changing the "Address" field for a PAC file in proxy configuration of IE (see image). This field is set to blank when I execute this code. I need to set this field to "http://proxy.pac/" or whatever... I think the red-colored line is the responsible of this behavior. I suppose the way I'm setting the PAC file address is not correct.

Any ideas on how to do it?

Thank you for your time!
Attached Images
File Type: png ie_proxy_pac.png (32.5 KB, 2 views)
__________________
01000011011010000110000101110010011011000110100101100101
~ En mi vida sólo hay dos días que no me importan: ayer y mañana ~
Reply With Quote