2022-07-14 12:30:57 +00:00
|
|
|
package settings
|
2022-07-14 06:04:57 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
|
2022-07-14 12:30:57 +00:00
|
|
|
F "github.com/sagernet/sing/common/format"
|
|
|
|
|
2022-07-14 06:04:57 +00:00
|
|
|
"golang.org/x/sys/windows"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2022-07-14 12:30:57 +00:00
|
|
|
modwininet = windows.NewLazySystemDLL("settings.dll")
|
2022-07-14 06:04:57 +00:00
|
|
|
procInternetSetOptionW = modwininet.NewProc("InternetSetOptionW")
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
internetOptionPerConnectionOption = 75
|
|
|
|
internetOptionSettingsChanged = 39
|
|
|
|
internetOptionRefresh = 37
|
|
|
|
internetOptionProxySettingsChanged = 95
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
internetPerConnFlags = 1
|
|
|
|
internetPerConnProxyServer = 2
|
|
|
|
internetPerConnProxyBypass = 3
|
|
|
|
internetPerConnAutoconfigUrl = 4
|
|
|
|
internetPerConnAutodiscoveryFlags = 5
|
|
|
|
internetPerConnAutoconfigSecondaryUrl = 6
|
|
|
|
internetPerConnAutoconfigReloadDelayMins = 7
|
|
|
|
internetPerConnAutoconfigLastDetectTime = 8
|
|
|
|
internetPerConnAutoconfigLastDetectUrl = 9
|
|
|
|
internetPerConnFlagsUi = 10
|
|
|
|
internetOptionProxyUsername = 43
|
|
|
|
internetOptionProxyPassword = 44
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
proxyTypeDirect = 1
|
|
|
|
proxyTypeProxy = 2
|
|
|
|
proxyTypeAutoProxyUrl = 4
|
|
|
|
proxyTypeAutoDetect = 8
|
|
|
|
)
|
|
|
|
|
|
|
|
type internetPerConnOptionList struct {
|
|
|
|
dwSize uint32
|
|
|
|
pszConnection uintptr
|
|
|
|
dwOptionCount uint32
|
|
|
|
dwOptionError uint32
|
|
|
|
pOptions uintptr
|
|
|
|
}
|
|
|
|
|
|
|
|
type internetPerConnOption struct {
|
|
|
|
dwOption uint32
|
|
|
|
value [8]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func internetSetOption(option uintptr, lpBuffer uintptr, dwBufferSize uintptr) error {
|
|
|
|
r0, _, err := syscall.SyscallN(procInternetSetOptionW.Addr(), 0, option, lpBuffer, dwBufferSize)
|
|
|
|
if r0 != 1 {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func setOptions(options ...internetPerConnOption) error {
|
|
|
|
var optionList internetPerConnOptionList
|
|
|
|
optionList.dwSize = uint32(unsafe.Sizeof(optionList))
|
|
|
|
optionList.dwOptionCount = uint32(len(options))
|
|
|
|
optionList.dwOptionError = 0
|
|
|
|
optionList.pOptions = uintptr(unsafe.Pointer(&options[0]))
|
|
|
|
err := internetSetOption(internetOptionPerConnectionOption, uintptr(unsafe.Pointer(&optionList)), uintptr(optionList.dwSize))
|
|
|
|
if err != nil {
|
|
|
|
return os.NewSyscallError("InternetSetOption(Direct)", err)
|
|
|
|
}
|
|
|
|
err = internetSetOption(internetOptionSettingsChanged, 0, 0)
|
|
|
|
if err != nil {
|
|
|
|
return os.NewSyscallError("InternetSetOption(SettingsChanged)", err)
|
|
|
|
}
|
|
|
|
err = internetSetOption(internetOptionProxySettingsChanged, 0, 0)
|
|
|
|
if err != nil {
|
|
|
|
return os.NewSyscallError("InternetSetOption(ProxySettingsChanged)", err)
|
|
|
|
}
|
|
|
|
err = internetSetOption(internetOptionRefresh, 0, 0)
|
|
|
|
if err != nil {
|
|
|
|
return os.NewSyscallError("InternetSetOption(Refresh)", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ClearSystemProxy() error {
|
|
|
|
var flagsOption internetPerConnOption
|
|
|
|
flagsOption.dwOption = internetPerConnFlags
|
|
|
|
*((*uint32)(unsafe.Pointer(&flagsOption.value))) = proxyTypeDirect | proxyTypeAutoDetect
|
|
|
|
return setOptions(flagsOption)
|
|
|
|
}
|
|
|
|
|
2022-07-14 12:30:57 +00:00
|
|
|
func SetSystemProxy(port uint16, mixed bool) error {
|
2022-07-14 06:04:57 +00:00
|
|
|
var flagsOption internetPerConnOption
|
|
|
|
flagsOption.dwOption = internetPerConnFlags
|
|
|
|
*((*uint32)(unsafe.Pointer(&flagsOption.value))) = proxyTypeProxy | proxyTypeDirect
|
|
|
|
var proxyOption internetPerConnOption
|
|
|
|
proxyOption.dwOption = internetPerConnProxyServer
|
2022-07-14 12:30:57 +00:00
|
|
|
*((*uintptr)(unsafe.Pointer(&proxyOption.value))) = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(F.ToString("http://127.0.0.1:", port))))
|
2022-07-14 06:04:57 +00:00
|
|
|
var bypassOption internetPerConnOption
|
|
|
|
bypassOption.dwOption = internetPerConnProxyBypass
|
2022-07-14 12:30:57 +00:00
|
|
|
*((*uintptr)(unsafe.Pointer(&bypassOption.value))) = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr("local")))
|
2022-07-14 06:04:57 +00:00
|
|
|
return setOptions(flagsOption, proxyOption, bypassOption)
|
|
|
|
}
|