mirror of
https://github.com/safing/portbase
synced 2025-09-01 18:19:57 +00:00
Add GetServiceNames (svchost.exe)
This commit is contained in:
parent
cf365e2e00
commit
3a7a21495d
2 changed files with 120 additions and 0 deletions
118
utils/osdetail/svchost_windows.go
Normal file
118
utils/osdetail/svchost_windows.go
Normal file
|
@ -0,0 +1,118 @@
|
|||
package osdetail
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
serviceNames map[int32]string
|
||||
serviceNamesLock sync.Mutex
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrServiceNotFound = errors.New("no service with the given PID was found")
|
||||
)
|
||||
|
||||
// GetServiceNames returns all service names assosicated with a svchost.exe process on Windows.
|
||||
func GetServiceNames(pid int32) (string, error) {
|
||||
serviceNamesLock.Lock()
|
||||
defer serviceNamesLock.Unlock()
|
||||
|
||||
if serviceNames != nil {
|
||||
names, ok := serviceNames[pid]
|
||||
if ok {
|
||||
return names, nil
|
||||
}
|
||||
}
|
||||
|
||||
serviceNames, err := GetAllServiceNames()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
names, ok := serviceNames[pid]
|
||||
if ok {
|
||||
return names, nil
|
||||
}
|
||||
|
||||
return "", ErrServiceNotFound
|
||||
}
|
||||
|
||||
// GetAllServiceNames returns a list of service names assosicated with svchost.exe processes on Windows.
|
||||
func GetAllServiceNames() (map[int32]string, error) {
|
||||
output, err := exec.Command("tasklist", "/svc", "/fi", "imagename eq svchost.exe").Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get svchost tasklist: %s", err)
|
||||
}
|
||||
|
||||
// file scanner
|
||||
scanner := bufio.NewScanner(bytes.NewReader(output))
|
||||
scanner.Split(bufio.ScanLines)
|
||||
|
||||
// skip output header
|
||||
for scanner.Scan() {
|
||||
if strings.HasPrefix(scanner.Text(), "=") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
pid int32
|
||||
services string
|
||||
collection = make(map[int32]string)
|
||||
)
|
||||
|
||||
for scanner.Scan() {
|
||||
// get fields of line
|
||||
fields := strings.Fields(scanner.Text())
|
||||
|
||||
// check fields length
|
||||
if len(fields) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// new entry
|
||||
if fields[0] == "svchost.exe" {
|
||||
// save old entry
|
||||
if pid != 0 {
|
||||
collection[pid] = services
|
||||
}
|
||||
// reset
|
||||
pid = 0
|
||||
services = ""
|
||||
|
||||
// check fields length
|
||||
if len(fields) < 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
// get pid
|
||||
i, err := strconv.ParseInt(fields[1], 10, 32)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pid = int32(i)
|
||||
|
||||
// skip used fields
|
||||
fields = fields[2:]
|
||||
}
|
||||
|
||||
// add service names
|
||||
services += " " + strings.Join(fields, " ")
|
||||
}
|
||||
|
||||
if pid != 0 {
|
||||
// save last entry
|
||||
collection[pid] = services
|
||||
}
|
||||
|
||||
return collection, nil
|
||||
}
|
|
@ -7,6 +7,8 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// FIXME: use https://godoc.org/github.com/shirou/gopsutil/host#PlatformInformation instead
|
||||
|
||||
var (
|
||||
versionRe = regexp.MustCompile(`[0-9\.]+`)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue