commit | 301114b31cced3624480dfb114ca1b495ec69aa5 | [log] [tgz] |
---|---|---|
author | Jason A. Donenfeld <Jason@zx2c4.com> | Thu Jun 06 17:27:41 2019 +0200 |
committer | Jason Donenfeld <Jason@zx2c4.com> | Sun Jun 09 08:25:36 2019 +0000 |
tree | b2a7dcfe734bfe933a8abd940b8732e46e76d8e9 | |
parent | 6df407bc07cea62a53772325c60de06a3c869dd2 [diff] |
windows: allow determining if manager is locked The SCM can be locked by NT. While traditionally any process could lock the SCM using "LockServiceDatabase", Microsoft removed this functionality because it created so many bugs, and that function now does nothing. However, the system itself, via the "NT Service Control Manager", is still allowed to lock the SCM. For example, at boot time on Windows 8.1, the SCM is locked after a service is started until that service reports itself in a running state. This poses a bit of a problem: it's useful to install device drivers from inside services as part of their initialization, and mark the service as having started only after the device has installed. But device installation might potentially load new drivers, and drivers themselves exist as a special type of service. This means that if a driver is installed before marking the service as started, the entire SCM will deadlock, and the OS will be partially unresponsive for a minute or two. Fortunately Microsoft supplies an API for exactly this purpose. The solution is to mark the service as started before installing device drivers, only under the circumstance that the SCM is locked. So, this commit adds the proper API for determining this. It can be used like this: if m, err := mgr.Connect(); err == nil { if lockStatus, err := m.LockStatus(); err == nil && lockStatus.IsLocked { log.Printf("SCM locked for %v by %s, marking service as started", lockStatus.Age, lockStatus.Owner) changes <- svc.Status{State: svc.Running} } m.Disconnect() } deviceDriver.Install() This creates messages like the following, indicating that this API works: SCM locked for 1s by .\NT Service Control Manager, marking service as started Change-Id: Ic2f5b387e23efc3a287b2ab96ff84b357b712e36 Reviewed-on: https://go-review.googlesource.com/c/sys/+/180977 Run-TryBot: Jason Donenfeld <Jason@zx2c4.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This repository holds supplemental Go packages for low-level interactions with the operating system.
The easiest way to install is to run go get -u golang.org/x/sys
. You can also manually git clone the repository to $GOPATH/src/golang.org/x/sys
.
This repository uses Gerrit for code changes. To learn how to submit changes to this repository, see https://golang.org/doc/contribute.html.
The main issue tracker for the sys repository is located at https://github.com/golang/go/issues. Prefix your issue with “x/sys:” in the subject line, so it is easy to find.