From 80fb842345e85053302243b1a2e1107925be1f11 Mon Sep 17 00:00:00 2001 From: Indexyz <7685264+5aaee9@users.noreply.github.com> Date: Sat, 1 Jun 2024 14:42:57 +0800 Subject: [PATCH] feat: detect ie config pac url for windows --- pkgs/platform/windows/string.go | 18 ++++++++++++++ pkgs/proxy/sysproxy/sysproxy_test.go | 2 ++ pkgs/proxy/sysproxy/sysproxy_windows.go | 31 +++++++++++++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 pkgs/platform/windows/string.go diff --git a/pkgs/platform/windows/string.go b/pkgs/platform/windows/string.go new file mode 100644 index 0000000..a6bf8ad --- /dev/null +++ b/pkgs/platform/windows/string.go @@ -0,0 +1,18 @@ +package windows + +import ( + "unicode/utf16" + "unsafe" +) + +func GoWString(s *uint16) string { + if s == nil { + return "" + } + p := (*[1<<30 - 1]uint16)(unsafe.Pointer(s)) + sz := 0 + for p[sz] != 0 { + sz++ + } + return string(utf16.Decode(p[:sz:sz])) +} diff --git a/pkgs/proxy/sysproxy/sysproxy_test.go b/pkgs/proxy/sysproxy/sysproxy_test.go index cbdb02a..2bd9cbc 100644 --- a/pkgs/proxy/sysproxy/sysproxy_test.go +++ b/pkgs/proxy/sysproxy/sysproxy_test.go @@ -1,3 +1,5 @@ +//go:build windows || darwin + package sysproxy import ( diff --git a/pkgs/proxy/sysproxy/sysproxy_windows.go b/pkgs/proxy/sysproxy/sysproxy_windows.go index 65c49d2..c293997 100644 --- a/pkgs/proxy/sysproxy/sysproxy_windows.go +++ b/pkgs/proxy/sysproxy/sysproxy_windows.go @@ -5,6 +5,7 @@ import ( "syscall" "unsafe" + pWin "github.com/5aaee9/utils/pkgs/platform/windows" "golang.org/x/sys/windows" ) @@ -17,9 +18,11 @@ func NewSystemProxy() SystemProxy { var _ SystemProxy = (*WindowsSystemProxy)(nil) var ( - modwininet = windows.NewLazySystemDLL("wininet.dll") - procInternetSetOptionW = modwininet.NewProc("InternetSetOptionW") - procInternetQueryOptionA = modwininet.NewProc("InternetQueryOptionA") + modwininet = windows.NewLazySystemDLL("wininet.dll") + modwinhttp = windows.NewLazySystemDLL("winhttp.dll") + procInternetSetOptionW = modwininet.NewProc("InternetSetOptionW") + procInternetQueryOptionA = modwininet.NewProc("InternetQueryOptionA") + procWinHttpGetIEProxyConfigForCurrentUser = modwinhttp.NewProc("WinHttpGetIEProxyConfigForCurrentUser") ) const ( @@ -71,6 +74,13 @@ type internetProxyInfo struct { lpszProxyBypass *uint16 } +type winHttpCurrentUserIEProxyConfig struct { + fAutoDetect bool + lpszAutoConfigUrl *uint16 + lpszProxy *uint16 + lpszProxyBypass *uint16 +} + func internetSetOption(option uintptr, lpBuffer uintptr, dwBufferSize uintptr) error { r0, _, err := syscall.SyscallN(procInternetSetOptionW.Addr(), 0, option, lpBuffer, dwBufferSize) if r0 != 1 { @@ -146,11 +156,24 @@ func (p *WindowsSystemProxy) Status() (*SystemProxyStatus, error) { return nil, err } + ieConfig := winHttpCurrentUserIEProxyConfig{} + r0, _, err = syscall.SyscallN(procWinHttpGetIEProxyConfigForCurrentUser.Addr(), uintptr(unsafe.Pointer(&ieConfig))) + + if r0 != 1 { + return nil, err + } + proxyInfo := (*internetProxyInfo)(unsafe.Pointer(&buffer[0])) res := &SystemProxyStatus{} - res.State = proxyInfo.dwAccessType != 1 + if proxyInfo.dwAccessType != 1 { + res.State = true + } + + if len(pWin.GoWString(ieConfig.lpszAutoConfigUrl)) > 0 { + res.State = true + } return res, nil }