The Windows compilers appear to align JOBOBJECT_BASIC_LIMIT_INFORMATION
to an 8-byte boundary, which on 32-bit systems means adding 32 bits of
padding. Unfortunately we can't always add a padding field, because
no padding is required on a 64-bit system. So use different versions
of the struct for different targets.
Fixesgolang/go#41001
Change-Id: I38d14edfd3f3a80da22825455f20e1f7de136638
Reviewed-on: https://go-review.googlesource.com/c/sys/+/251197
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marc-Antoine Ruel <maruel@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
I noticed that we call syscall in servicemain without aligning stack.
That is against Windows rules, so align the stack as required.
I tried running this code with specifically non-aligned stack (I aligned
stack, and then subtracted 1 from SP) on my Windows 10 to test this
change. But it makes no difference on my Windows 10 PC - I built and run
golang.org/x/sys/windows/svc/example, and it runs successfully
regardless of stack alignment. But alignment might make difference on
other computers.
Maybe fixesgolang/go#40160
Change-Id: I351f7f730fba4aa6dc409a79de4ad737b4a0a7d4
Reviewed-on: https://go-review.googlesource.com/c/sys/+/246317
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This CL fixes unsafe casts to slices that are missing length or capacity.
Running tests with -d=checkptr enabled may panic on casting unsafe.Pointer to a static array of large predefined length, that is most likely much bigger than the size of the actual array in memory. Checkptr check is not satisfied if slicing operator misses length and capacity arguments `(*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]`, or when there is no slicing at all `(*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))`.
To find all potential cases I used `grep -nr ")(unsafe.Pointer(" ./windows`, then filtered out safe casts when object size is always static and known at compile time.
To reproduce the issue run tests with checkptr enabled `go test -a -gcflags=all=-d=checkptr ./windows/...`.
Updates golang/go#34972Fixesgolang/go#38355
Change-Id: I9dd2084b4f9fb7618cdb140fb2f38b56b6d6cc04
GitHub-Last-Rev: 73288ad18a
GitHub-Pull-Request: golang/sys#65
Reviewed-on: https://go-review.googlesource.com/c/sys/+/225418
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit adds the following MUI functions:
- GetUserPreferredUILanguages
- GetSystemPreferredUILanguages
- GetThreadPreferredUILanguages
- GetProcessPreferredUILanguages
Change-Id: I44f1c07245ab814935778c6b910b224d24cc753c
Reviewed-on: https://go-review.googlesource.com/c/sys/+/207860
Reviewed-by: Simon Rozman <simon@rozman.si>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
CL 199519 broke the build with Go 1.11. Even though this is not an
officially supported release anymore, people still seem to rely on it
and the fix is easy enough and won't break anyone using newer, supported
Go versions.
Change-Id: I632d6840bc1f49c01c372727c9a55d2daf98f4a8
Reviewed-on: https://go-review.googlesource.com/c/sys/+/206357
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This test's existence was predicated upon assumptions about the full
range of known data types and known data into those types. However,
we've learned from Microsoft that there are several undocumented secret
registry types that are in use by various parts of Windows, and we've
learned from inspection that many Microsoft uses of registry types don't
strictly adhere to the recommended value size. It's therefore foolhardy
to make any assumptions about what goes in and out of the registry, and
so this test is meaningless and error-prone.
Updates golang/go#35084
Change-Id: Ie545229afd8dc5bde90fffa0f735f7102cd4a6eb
Reviewed-on: https://go-review.googlesource.com/c/sys/+/203605
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
According to MSDN, "If the data has the REG_SZ, REG_MULTI_SZ or
REG_EXPAND_SZ type, this size includes any terminating null character or
characters unless the data was stored without them. [...] If the data
has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not
have been stored with the proper terminating null characters. Therefore,
even if the function returns ERROR_SUCCESS, the application should
ensure that the string is properly terminated before using it;
otherwise, it may overwrite a buffer."
It's therefore dangerous to pass it off unbounded as we do, and in fact
this led to crashes on real systems.
Change-Id: I2ab324e85f75dc3e4d6d62fec3b96937fec77510
Reviewed-on: https://go-review.googlesource.com/c/sys/+/202957
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Chmod toggles the FILE_ATTRIBUTES_READONLY flag depending on the
permission bits. That's a bit odd but I guess some compromises were made
at some point and this is what was chosen to map to a Unix concept that
Windows doesn't really have in the same way. That's fine. However, the
logic used in Chmod was forgotten from Open, which then manifested
itself in various places, most recently, go modules' read-only behavior.
This corresonds with the syscall CL 202439.
Updates golang/go#35033
Change-Id: Id8e74c5205057a74a35eda213516780b79a2aed2
Reviewed-on: https://go-review.googlesource.com/c/sys/+/202440
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
ShellExecute is an ancient API with an unusual return signature. It
pretends to return an HINSTANCE for backwards compatibility with Windows
3, but it's actualy a fake HINSTANCE. What's really happening here,
according to MSDN, is that it returns either an Windows error less
than or equal to 32, or it succeeds. So we adjust the return value
accordingly.
Prior to this commit, it was impossible to tell whether this command had
succeeded. For example, when using the "runas" verb, ShellExecute did
not correctly indicate whether or not permission was granted.
Change-Id: Ie60554d6465798bacb9a225c4ead7e8dd62bce14
Reviewed-on: https://go-review.googlesource.com/c/sys/+/199521
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nenad Kozul <knenad@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This allows us to modify this file and fix it more fluidly. Users can
invoke it from go generate via:
go run golang.org/x/sys/windows/mkwinsyscall
This was taken from Go repo commit 6b85fa80.
Updates golang/go#34388
Change-Id: I8dc39eed96b2499ccbde53554b3e16e6c1f6aa98
Reviewed-on: https://go-review.googlesource.com/c/sys/+/198637
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
From MSDN on CreateServiceW:
The returned handle is only valid for the process that called
CreateService. It can be closed by calling the CloseServiceHandle
function.
This isn't an actual kernel object to be closed with CloseHandle.
Change-Id: Iee225a666576d57a6c4864abef20206d54cbbce2
Reviewed-on: https://go-review.googlesource.com/c/sys/+/198298
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Changes in syscall_windows.go were copied from
internal/syscall/syscall_windows.go.
zsyscall_windows.go was regenerated by running
'go generate -tags=generate golang.org/x/sys/windows'
using a toolchain built from tip (after CL 196122).
These functions are called by cmd/go/internal/lockedfile via
internal/syscall/windows. I'd like to copy lockedfile into another
project (CL 197299), but these functions need to be exposed here in
order to do so. We may need these in x/mod eventually, too.
Change-Id: I2033106d2ba65009e764591bfe5702f4d41dffdd
Reviewed-on: https://go-review.googlesource.com/c/sys/+/198060
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
There's no point in adding a function call to retrieve a constant, or
worse, a syscall to retrieve a constant. These are fixed and baked so
deep into NT they'll never change. So let's benefit from the obvious
optimization and make these constants. Go easily inlines the function
calls as well. We also take the opportunity to sunset
OpenCurrentProcessToken and restore its original behavior, since users
should be invoking this deliberately with the correct access mask.
Change-Id: I92f7de56c0fcf5b69b59f5a79d2828c7ddf3c8f6
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196800
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This function shouldn't return an error. Like other String() functions
everywhere in Golang, this should instead return empty or a token value
during an error, so that it can be passed to %v and similar. Also, allow
for SID strings of maximum size.
Change-Id: Ib6d8407f8ad0bdabcb22c31b8f387594f2ea7672
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196799
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
GetCurrentProcess and GetCurrentThread return -1 and -2 respectively. We
could arguably hard code those values, but MSDN cautions not to; I'm
sure this advice is old now, given that the psuedo handles for tokens
(not processes/threads) are now implemented with inline functions in the
headers for Windows 8, but anyway, we'll follow Microsoft's advice.
However, regardless of that, these functions never ever return an error.
MSDN doesn't indicate that they do, reverse engineering the functions
doesn't indicate that they do, and checking against 0 is just plain
wrong, considering 0!=INVALID_HANDLE_VALUE; however
INVALID_HANDLE_VALUE==-1, so that's not correct either. In fact,
checking any value and returning any error does not make sense.
Incidently having to check code for the pseudo handle is more verbose
too.
In order to make this function do the correct thing and meet the spec,
remove the error value from the return.
Change-Id: If03c9dab001be3bf5a04999aef20dbfcf8a4f405
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196798
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
The SECURITY_ATTRIBUTES struct always takes a SECURITY_DESCRIPTOR
pointer. Now that we've defined SECURITY_DESCRIPTOR, make
SECURITY_ATTRIBUTES properly specify the type. This eliminates the need
for terrible uintptr(unsafe.Pointer(...)) casts everywhere.
Change-Id: Ibbc85524cfe33589d43f963e10aa19d7f47686f2
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196797
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This adds the basic foundation for dealing with security descriptors and
access control lists. The basic creators and getters are included in
this patch. These are some of the most fundamental security objects on NT,
and any work with the security API is fairly limited without it. These
are "core" NT structures.
Change-Id: I9a6399cb6ee41a825de30d5364ab69102d5f6d57
Reviewed-on: https://go-review.googlesource.com/c/sys/+/195498
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Windows type PBOOL is a pointer to a 4 byte value, where 0 means false
and not-0 means true. That means we should use uint32 here, not bool,
since Go bools can be 1 byte. This commit was re-generated using
mksyscall_windows.go from CL 196122.
Updates: golang/go#34364
Change-Id: I8e83b9a09c0b58d14ac9a7dee316553940ac6ee3
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196123
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
There are a few functions to control the behavior of shutdown and
logout, both for what the current process does during shutdown, and also
whether or not the current process is running in an interactive session.
The below code is a port of the MSDN example code to Go using one of the
added new functions:
https://docs.microsoft.com/en-us/windows/win32/shutdown/how-to-shut-down-the-system
func shutdownLikeMSDNDoes() error {
seShutdownName, err := windows.UTF16PtrFromString("SeShutdownPrivilege")
if err != nil {
return err
}
var shutdownPriv windows.Tokenprivileges
err = windows.LookupPrivilegeValue(nil, seShutdownName, &shutdownPriv.Privileges[0].Luid)
if err != nil {
return err
}
shutdownPriv.Privileges[0].Attributes = windows.SE_PRIVILEGE_ENABLED
shutdownPriv.PrivilegeCount = 1
process, err := windows.GetCurrentProcess()
if err != nil {
return err
}
var token windows.Token
err = windows.OpenProcessToken(process, windows.TOKEN_ADJUST_PRIVILEGES | windows.TOKEN_QUERY, &token)
if err != nil {
return err
}
defer token.Close()
err = windows.AdjustTokenPrivileges(token, false, &shutdownPriv, 0, nil, nil)
if err != nil {
return err
}
err = windows.ExitWindowsEx(windows.EWX_SHUTDOWN | windows.EWX_FORCE,
windows.SHTDN_REASON_MAJOR_OPERATINGSYSTEM | windows.SHTDN_REASON_MINOR_UPGRADE | windows.SHTDN_REASON_FLAG_PLANNED)
if err != nil {
return err
}
return nil
}
Note, though, that this function doesn't set the token privs back to how
they were before, which isn't good. A more robust method than the MSDN
one above would be to duplicate&impersonate.
Fixes: golang/go#34271
Change-Id: Ibe55ddd35b709d9ab793cb9af47c39901c5e5c69
Reviewed-on: https://go-review.googlesource.com/c/sys/+/195497
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bruce Downs <bruceadowns@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
A usual thing to ask is, "Is my current token in group X?" The right way
of doing such a thing is:
processToken, err := windows.OpenCurrentProcessToken()
if err != nil {
return false, err
}
defer processToken.Close()
var checkableToken windows.Token
err = windows.DuplicateTokenEx(token, windows.TOKEN_QUERY | windows.TOKEN_IMPERSONATE, nil, windows.SecurityIdentification, windows.TokenImpersonation, &checkableToken)
if err != nil {
return false, err
}
defer checkableToken.Close()
isMember, err := checkableToken.IsMember(someSID)
return isMember && err == nil, nil
This is the same flow that's used by, for example, shell32's internal
_LUAIsTokenAdmin function.
However, this all fails unless the original token is opened with
duplicate access. So this commit adjusts OpenCurrentProcessToken to do
the right thing.
Change-Id: I18efdfde43097ea9d10758018b0df132fba819f5
Reviewed-on: https://go-review.googlesource.com/c/sys/+/192337
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Simon Rozman <simon@rozman.si>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Indeed Go has mutexes of its own, but these are considerably
different from the native Windows ones, that can work across processes
and be put in various namespaces. They're an essential part of Windows
systems programming and important for interfacing with various external
interfaces.
Change-Id: I03987800ed1c134442321678c2c7d7aa359ecb36
Reviewed-on: https://go-review.googlesource.com/c/sys/+/192497
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The Go runtime disables priority boosting because it interferes with the
scheduler timer threads in some cases. But some apps might want to
re-enable it for specific reasons, so this commit adds the function to
do so.
Change-Id: Ida68b9f2b188560b46c322197461dd06453329e2
Reviewed-on: https://go-review.googlesource.com/c/sys/+/191839
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
While RtlGetVersion was added so that users can get the Windows version
that isn't affected by manifesting, RtlGetVersion is still stubbed out
by the application compatibility layer (aclayers.dll and apphelp.dll)
for certain processes, such as msiexec.exe, rendering these functions
useless for actually determining the underlying operating system. This
matters in the case of msiexec.exe using a custom action DLL to install
a kernel driver, which of course is version specific. This is also
useful, it turns out, for the C runtime library, in which Microsoft uses
this function too. It's existed as a stable interface since Windows XP,
has Wine support, and is used in a decent amount of software.
Change-Id: If391e43bc6d798eff6803d5a7aa6a179f2b31d88
Reviewed-on: https://go-review.googlesource.com/c/sys/+/188119
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Other functions, like GetVersion(), will lie about the OS version
depending on various win32 and manifest compatibility shims in place.
Calling RtlGetVersion is the proper way to retrieve the true OS version.
Change-Id: I2bd6d097dd763df51617cd825dc0ad300abf6212
Reviewed-on: https://go-review.googlesource.com/c/sys/+/182718
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matt Layher <mdlayher@gmail.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
This adds the recommended API for determining well-known folder paths,
such as where to place application configuration data. The MSDN
documentation mentions an optimization for the "current user" by passing
NULL as the token, so we provide both variants.
Updates golang/go#32248
Change-Id: I4a2d5d833543e6a0ba8f318944dd6493a0ec31d3
Reviewed-on: https://go-review.googlesource.com/c/sys/+/181637
Reviewed-by: Jason Donenfeld <Jason@zx2c4.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
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>