2024-10-28 20:24:08 +00:00
|
|
|
//go:build windows
|
|
|
|
|
2024-08-31 16:15:50 +00:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2024-09-23 16:45:27 +00:00
|
|
|
"fmt"
|
2024-08-31 16:27:24 +00:00
|
|
|
"strings"
|
2024-08-31 16:15:50 +00:00
|
|
|
|
2024-08-31 16:27:24 +00:00
|
|
|
"github.com/Baipyrus/ProxySwitcher/util"
|
2024-08-31 16:15:50 +00:00
|
|
|
"golang.org/x/sys/windows/registry"
|
|
|
|
)
|
|
|
|
|
2024-10-01 18:13:47 +00:00
|
|
|
func processVars(cmd *util.Command, isVariableType bool) {
|
|
|
|
// If not a variable type, return early as there's nothing to replace
|
|
|
|
if !isVariableType {
|
|
|
|
return
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:13:47 +00:00
|
|
|
// Replace specific $PRSW_ARG in the command's Name with each argument
|
|
|
|
for _, arg := range cmd.Arguments {
|
|
|
|
cmd.Name = strings.Replace(cmd.Name, "$PRSW_ARG", arg, 1)
|
|
|
|
}
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
func injectProxy(cmd *util.Command, variant *util.Variant, proxyServer string) {
|
|
|
|
// Skip if no proxy is provided or proxy option is discarded
|
2024-09-12 21:17:41 +00:00
|
|
|
if proxyServer == "" || variant.DiscardProxy {
|
2024-10-01 18:19:02 +00:00
|
|
|
return
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
// Surround 'proxyServer' with the provided surround string, if any
|
2024-09-23 16:45:27 +00:00
|
|
|
if variant.Surround != "" {
|
|
|
|
proxyServer = fmt.Sprintf("%[1]s%[2]s%[1]s", variant.Surround, proxyServer)
|
|
|
|
}
|
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
// Insert proxy into last place of command if the variant is VARIABLE
|
|
|
|
if variant.Type == util.VARIABLE && strings.Count(cmd.Name, "$PRSW_ARG") == 1 {
|
|
|
|
cmd.Name = strings.Replace(cmd.Name, "$PRSW_ARG", proxyServer, 1)
|
|
|
|
return
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
// Insert proxy after the equator if specified
|
2024-08-31 16:27:24 +00:00
|
|
|
if variant.Equator != "" {
|
2024-10-01 18:19:02 +00:00
|
|
|
lastArgIdx := len(cmd.Arguments) - 1
|
|
|
|
cmd.Arguments[lastArgIdx] += variant.Equator + proxyServer
|
|
|
|
return
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
// Otherwise, append the proxy as a new argument
|
|
|
|
cmd.Arguments = append(cmd.Arguments, proxyServer)
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
2024-10-01 18:09:54 +00:00
|
|
|
func generateCommands(base string, variants []*util.Variant, proxyServer string) []*util.Command {
|
2024-08-31 16:27:24 +00:00
|
|
|
var commands []*util.Command
|
|
|
|
|
2024-10-01 18:09:54 +00:00
|
|
|
// Iterate through all variants and generate a command for each
|
2024-08-31 16:27:24 +00:00
|
|
|
for _, variant := range variants {
|
2024-10-01 18:00:31 +00:00
|
|
|
isVariableType := variant.Type == util.VARIABLE
|
2024-08-31 16:27:24 +00:00
|
|
|
|
2024-10-01 18:09:54 +00:00
|
|
|
// Create command from default parameters
|
|
|
|
cmd := &util.Command{
|
|
|
|
Name: base,
|
|
|
|
Arguments: append([]string{}, variant.Arguments...),
|
|
|
|
}
|
|
|
|
|
2024-10-01 18:13:47 +00:00
|
|
|
processVars(cmd, isVariableType)
|
2024-10-01 18:19:02 +00:00
|
|
|
injectProxy(cmd, variant, proxyServer)
|
2024-08-31 16:27:24 +00:00
|
|
|
|
2024-10-01 18:19:02 +00:00
|
|
|
commands = append(commands, cmd)
|
2024-08-31 16:27:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return commands
|
|
|
|
}
|
|
|
|
|
2024-08-31 16:15:50 +00:00
|
|
|
func ReadSystemProxy() (*Proxy, error) {
|
2024-09-08 19:46:35 +00:00
|
|
|
// Open registry key for internet settings
|
2024-08-31 16:15:50 +00:00
|
|
|
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.QUERY_VALUE)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer key.Close()
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Read registry value for proxy enabled
|
2024-09-08 19:06:31 +00:00
|
|
|
enableVal, _, err := key.GetIntegerValue("proxyEnable")
|
2024-08-31 16:15:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-09-08 19:46:35 +00:00
|
|
|
// Convert int value to bool
|
2024-09-08 19:06:31 +00:00
|
|
|
enabled := enableVal != 0
|
2024-08-31 16:15:50 +00:00
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Read registry value for proxy servers
|
2024-09-08 19:06:31 +00:00
|
|
|
servers, _, err := key.GetStringValue("proxyServer")
|
2024-08-31 16:15:50 +00:00
|
|
|
if err != nil && !errors.Is(err, registry.ErrNotExist) {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Use entire value if singular server
|
2024-09-12 21:39:02 +00:00
|
|
|
proxy := &Proxy{Enabled: enabled, Server: ""}
|
2024-09-08 19:06:31 +00:00
|
|
|
if !strings.ContainsAny(servers, ";=") {
|
2024-09-12 21:39:02 +00:00
|
|
|
proxy.Server = servers
|
|
|
|
return proxy, nil
|
2024-09-08 19:06:31 +00:00
|
|
|
}
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Map proxy servers into dictionary
|
2024-09-08 19:06:31 +00:00
|
|
|
serverSplit := strings.Split(servers, ";")
|
|
|
|
serverDict := make(map[string]string)
|
|
|
|
for _, substr := range serverSplit {
|
|
|
|
subSplit := strings.Split(substr, "=")
|
|
|
|
key, value := subSplit[0], subSplit[1]
|
|
|
|
serverDict[key] = value
|
|
|
|
}
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Grab HTTP proxy server first
|
2024-09-08 19:06:31 +00:00
|
|
|
if serverDict["http"] != "" {
|
2024-09-12 21:39:02 +00:00
|
|
|
proxy.Server = serverDict["http"]
|
|
|
|
return proxy, nil
|
2024-09-08 19:06:31 +00:00
|
|
|
}
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Grab HTTP proxy server second
|
2024-09-08 19:06:31 +00:00
|
|
|
if serverDict["https"] != "" {
|
2024-09-12 21:39:02 +00:00
|
|
|
proxy.Server = serverDict["https"]
|
|
|
|
return proxy, nil
|
2024-09-08 19:06:31 +00:00
|
|
|
}
|
|
|
|
|
2024-09-12 21:39:02 +00:00
|
|
|
// Return with empty proxy server ("discarded"; not detected)
|
|
|
|
return proxy, nil
|
2024-08-31 16:15:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func SetSystemProxy(state bool) error {
|
2024-09-08 19:46:35 +00:00
|
|
|
// Open registry key for internet settings
|
2024-08-31 16:15:50 +00:00
|
|
|
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.SET_VALUE)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer key.Close()
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Get state as int instead of bool
|
2024-08-31 16:15:50 +00:00
|
|
|
var value uint32
|
|
|
|
if state {
|
|
|
|
value = 1
|
|
|
|
} else {
|
|
|
|
value = 0
|
|
|
|
}
|
|
|
|
|
2024-09-08 19:46:35 +00:00
|
|
|
// Write registry value to enable/disable proxy
|
2024-08-31 16:15:50 +00:00
|
|
|
err = key.SetDWordValue("proxyEnable", value)
|
2024-08-31 19:11:54 +00:00
|
|
|
return err
|
2024-08-31 16:15:50 +00:00
|
|
|
}
|