1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- package process
- import (
- "context"
- "net/netip"
- "syscall"
- "github.com/sagernet/sing-box/adapter"
- E "github.com/sagernet/sing/common/exceptions"
- "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 {
- return winiphlpapi.LoadExtendedTable()
- }
- func (s *windowsSearcher) FindProcessInfo(ctx context.Context, network string, source netip.AddrPort, destination netip.AddrPort) (*adapter.ConnectionOwner, error) {
- pid, err := winiphlpapi.FindPid(network, source)
- if err != nil {
- return nil, err
- }
- path, err := getProcessPath(pid)
- if err != nil {
- return &adapter.ConnectionOwner{ProcessID: pid, UserId: -1}, err
- }
- return &adapter.ConnectionOwner{ProcessID: pid, ProcessPath: path, UserId: -1}, nil
- }
- func getProcessPath(pid uint32) (string, error) {
- switch pid {
- case 0:
- return ":System Idle Process", nil
- case 4:
- return ":System", nil
- }
- handle, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid)
- if err != nil {
- return "", err
- }
- defer windows.CloseHandle(handle)
- size := uint32(syscall.MAX_LONG_PATH)
- buf := make([]uint16, syscall.MAX_LONG_PATH)
- err = windows.QueryFullProcessImageName(handle, 0, &buf[0], &size)
- if err != nil {
- return "", err
- }
- return windows.UTF16ToString(buf[:size]), nil
- }
|