sing-box/common/process/searcher_windows.go

62 lines
1.4 KiB
Go
Raw Normal View History

package process
import (
"context"
"net/netip"
"syscall"
E "github.com/sagernet/sing/common/exceptions"
2025-01-26 01:01:00 +00:00
"github.com/sagernet/sing/common/winiphlpapi"
"golang.org/x/sys/windows"
)
var _ Searcher = (*windowsSearcher)(nil)
type windowsSearcher struct{}
func NewSearcher(_ Config) (Searcher, error) {
err := initWin32API()
if err != nil {
return nil, E.Cause(err, "init win32 api")
}
return &windowsSearcher{}, nil
}
func initWin32API() error {
2025-01-26 01:01:00 +00:00
return winiphlpapi.LoadExtendedTable()
}
2022-08-20 02:38:12 +00:00
func (s *windowsSearcher) FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*Info, error) {
2025-01-26 01:01:00 +00:00
pid, err := winiphlpapi.FindPid(network, source)
if err != nil {
return nil, err
}
2025-01-26 01:01:00 +00:00
path, err := getProcessPath(pid)
if err != nil {
2025-01-26 01:01:00 +00:00
return &Info{ProcessID: pid, UserId: -1}, err
}
2025-01-26 01:01:00 +00:00
return &Info{ProcessID: pid, ProcessPath: path, UserId: -1}, nil
}
2025-01-26 01:01:00 +00:00
func getProcessPath(pid uint32) (string, error) {
switch pid {
case 0:
return ":System Idle Process", nil
case 4:
return ":System", nil
}
2025-01-26 01:01:00 +00:00
handle, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid)
if err != nil {
return "", err
}
2025-01-26 01:01:00 +00:00
defer windows.CloseHandle(handle)
size := uint32(syscall.MAX_LONG_PATH)
buf := make([]uint16, syscall.MAX_LONG_PATH)
2025-01-26 01:01:00 +00:00
err = windows.QueryFullProcessImageName(handle, 0, &buf[0], &size)
if err != nil {
return "", err
}
2025-01-26 01:01:00 +00:00
return windows.UTF16ToString(buf[:size]), nil
}