mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-06 09:07:16 -04:00
windows: add SubscribeServiceChangeNotifications for service tracking
Windows 8+ introduced SubscribeServiceChangeNotifications for simpler and more reliable service event tracking. This commit adds the function and related constants: https://docs.microsoft.com/en-us/windows/win32/services/subscribeservicechangenotifications Since these functions are only available on Windows 8+, and Go supports Windows 7+, we mark them with "?" so that the caller can handle graceful degradation. Change-Id: Ibb9708bbe797408701c70b4b1c715381f33cb8ee Reviewed-on: https://go-review.googlesource.com/c/sys/+/274576 Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Trust: Alex Brainman <alex.brainman@gmail.com> Trust: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -128,6 +128,10 @@ const (
|
|||||||
SERVICE_NOTIFY_CREATED = 0x00000080
|
SERVICE_NOTIFY_CREATED = 0x00000080
|
||||||
SERVICE_NOTIFY_DELETED = 0x00000100
|
SERVICE_NOTIFY_DELETED = 0x00000100
|
||||||
SERVICE_NOTIFY_DELETE_PENDING = 0x00000200
|
SERVICE_NOTIFY_DELETE_PENDING = 0x00000200
|
||||||
|
|
||||||
|
SC_EVENT_DATABASE_CHANGE = 0
|
||||||
|
SC_EVENT_PROPERTY_CHANGE = 1
|
||||||
|
SC_EVENT_STATUS_CHANGE = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
type SERVICE_STATUS struct {
|
type SERVICE_STATUS struct {
|
||||||
@@ -229,3 +233,5 @@ type QUERY_SERVICE_LOCK_STATUS struct {
|
|||||||
//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW
|
//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW
|
||||||
//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx
|
//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx
|
||||||
//sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW
|
//sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW
|
||||||
|
//sys SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) = sechost.SubscribeServiceChangeNotifications?
|
||||||
|
//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications?
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ var (
|
|||||||
modntdll = NewLazySystemDLL("ntdll.dll")
|
modntdll = NewLazySystemDLL("ntdll.dll")
|
||||||
modole32 = NewLazySystemDLL("ole32.dll")
|
modole32 = NewLazySystemDLL("ole32.dll")
|
||||||
modpsapi = NewLazySystemDLL("psapi.dll")
|
modpsapi = NewLazySystemDLL("psapi.dll")
|
||||||
|
modsechost = NewLazySystemDLL("sechost.dll")
|
||||||
modsecur32 = NewLazySystemDLL("secur32.dll")
|
modsecur32 = NewLazySystemDLL("secur32.dll")
|
||||||
modshell32 = NewLazySystemDLL("shell32.dll")
|
modshell32 = NewLazySystemDLL("shell32.dll")
|
||||||
moduser32 = NewLazySystemDLL("user32.dll")
|
moduser32 = NewLazySystemDLL("user32.dll")
|
||||||
@@ -329,6 +330,8 @@ var (
|
|||||||
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
||||||
procStringFromGUID2 = modole32.NewProc("StringFromGUID2")
|
procStringFromGUID2 = modole32.NewProc("StringFromGUID2")
|
||||||
procEnumProcesses = modpsapi.NewProc("EnumProcesses")
|
procEnumProcesses = modpsapi.NewProc("EnumProcesses")
|
||||||
|
procSubscribeServiceChangeNotifications = modsechost.NewProc("SubscribeServiceChangeNotifications")
|
||||||
|
procUnsubscribeServiceChangeNotifications = modsechost.NewProc("UnsubscribeServiceChangeNotifications")
|
||||||
procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
|
procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
|
||||||
procTranslateNameW = modsecur32.NewProc("TranslateNameW")
|
procTranslateNameW = modsecur32.NewProc("TranslateNameW")
|
||||||
procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
|
procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
|
||||||
@@ -2789,6 +2792,27 @@ func EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) {
|
||||||
|
ret = procSubscribeServiceChangeNotifications.Find()
|
||||||
|
if ret != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r0, _, _ := syscall.Syscall6(procSubscribeServiceChangeNotifications.Addr(), 5, uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
ret = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnsubscribeServiceChangeNotifications(subscription uintptr) (err error) {
|
||||||
|
err = procUnsubscribeServiceChangeNotifications.Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
syscall.Syscall(procUnsubscribeServiceChangeNotifications.Addr(), 1, uintptr(subscription), 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
|
func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
|
r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
|
||||||
if r1&0xff == 0 {
|
if r1&0xff == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user