wininet_windows.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package wininet
  2. import (
  3. "os"
  4. "syscall"
  5. "unsafe"
  6. "golang.org/x/sys/windows"
  7. )
  8. var (
  9. modwininet = windows.NewLazySystemDLL("wininet.dll")
  10. procInternetSetOptionW = modwininet.NewProc("InternetSetOptionW")
  11. )
  12. const (
  13. internetOptionPerConnectionOption = 75
  14. internetOptionSettingsChanged = 39
  15. internetOptionRefresh = 37
  16. internetOptionProxySettingsChanged = 95
  17. )
  18. const (
  19. internetPerConnFlags = 1
  20. internetPerConnProxyServer = 2
  21. internetPerConnProxyBypass = 3
  22. internetPerConnAutoconfigUrl = 4
  23. internetPerConnAutodiscoveryFlags = 5
  24. internetPerConnAutoconfigSecondaryUrl = 6
  25. internetPerConnAutoconfigReloadDelayMins = 7
  26. internetPerConnAutoconfigLastDetectTime = 8
  27. internetPerConnAutoconfigLastDetectUrl = 9
  28. internetPerConnFlagsUi = 10
  29. internetOptionProxyUsername = 43
  30. internetOptionProxyPassword = 44
  31. )
  32. const (
  33. proxyTypeDirect = 1
  34. proxyTypeProxy = 2
  35. proxyTypeAutoProxyUrl = 4
  36. proxyTypeAutoDetect = 8
  37. )
  38. type internetPerConnOptionList struct {
  39. dwSize uint32
  40. pszConnection uintptr
  41. dwOptionCount uint32
  42. dwOptionError uint32
  43. pOptions uintptr
  44. }
  45. type internetPerConnOption struct {
  46. dwOption uint32
  47. value [8]byte
  48. }
  49. func internetSetOption(option uintptr, lpBuffer uintptr, dwBufferSize uintptr) error {
  50. r0, _, err := syscall.SyscallN(procInternetSetOptionW.Addr(), 0, option, lpBuffer, dwBufferSize)
  51. if r0 != 1 {
  52. return err
  53. }
  54. return nil
  55. }
  56. func setOptions(options ...internetPerConnOption) error {
  57. var optionList internetPerConnOptionList
  58. optionList.dwSize = uint32(unsafe.Sizeof(optionList))
  59. optionList.dwOptionCount = uint32(len(options))
  60. optionList.dwOptionError = 0
  61. optionList.pOptions = uintptr(unsafe.Pointer(&options[0]))
  62. err := internetSetOption(internetOptionPerConnectionOption, uintptr(unsafe.Pointer(&optionList)), uintptr(optionList.dwSize))
  63. if err != nil {
  64. return os.NewSyscallError("InternetSetOption(Direct)", err)
  65. }
  66. err = internetSetOption(internetOptionSettingsChanged, 0, 0)
  67. if err != nil {
  68. return os.NewSyscallError("InternetSetOption(SettingsChanged)", err)
  69. }
  70. err = internetSetOption(internetOptionProxySettingsChanged, 0, 0)
  71. if err != nil {
  72. return os.NewSyscallError("InternetSetOption(ProxySettingsChanged)", err)
  73. }
  74. err = internetSetOption(internetOptionRefresh, 0, 0)
  75. if err != nil {
  76. return os.NewSyscallError("InternetSetOption(Refresh)", err)
  77. }
  78. return nil
  79. }
  80. func ClearSystemProxy() error {
  81. var flagsOption internetPerConnOption
  82. flagsOption.dwOption = internetPerConnFlags
  83. *((*uint32)(unsafe.Pointer(&flagsOption.value))) = proxyTypeDirect | proxyTypeAutoDetect
  84. return setOptions(flagsOption)
  85. }
  86. func SetSystemProxy(proxy string, bypass string) error {
  87. var flagsOption internetPerConnOption
  88. flagsOption.dwOption = internetPerConnFlags
  89. *((*uint32)(unsafe.Pointer(&flagsOption.value))) = proxyTypeProxy | proxyTypeDirect
  90. var proxyOption internetPerConnOption
  91. proxyOption.dwOption = internetPerConnProxyServer
  92. *((*uintptr)(unsafe.Pointer(&proxyOption.value))) = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(proxy)))
  93. var bypassOption internetPerConnOption
  94. bypassOption.dwOption = internetPerConnProxyBypass
  95. *((*uintptr)(unsafe.Pointer(&bypassOption.value))) = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(bypass)))
  96. return setOptions(flagsOption, proxyOption, bypassOption)
  97. }