mirror of
https://github.com/golang/sys.git
synced 2026-02-08 11:46:04 +03:00
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>