winutil.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package winutil contains misc Windows/Win32 helper functions.
  4. package winutil
  5. import (
  6. "os/user"
  7. )
  8. const (
  9. // RegBase is the registry path inside HKEY_LOCAL_MACHINE where registry settings
  10. // are stored. This constant is a non-empty string only when GOOS=windows.
  11. RegBase = regBase
  12. // RegPolicyBase is the registry path inside HKEY_LOCAL_MACHINE where registry
  13. // policies are stored. This constant is a non-empty string only when
  14. // GOOS=windows.
  15. RegPolicyBase = regPolicyBase
  16. )
  17. // GetPolicyString looks up a registry value in the local machine's path for
  18. // system policies, or returns empty string and the error.
  19. // Use this function to read values that may be set by sysadmins via the MSI
  20. // installer or via GPO. For registry settings that you do *not* want to be
  21. // visible to sysadmin tools, use GetRegString instead.
  22. //
  23. // This function will only work on GOOS=windows. Trying to run it on any other
  24. // OS will always return an empty string and ErrNoValue.
  25. // If value does not exist or another error happens, returns empty string and error.
  26. func GetPolicyString(name string) (string, error) {
  27. return getPolicyString(name)
  28. }
  29. // GetPolicyInteger looks up a registry value in the local machine's path for
  30. // system policies, or returns 0 and the associated error.
  31. // Use this function to read values that may be set by sysadmins via the MSI
  32. // installer or via GPO. For registry settings that you do *not* want to be
  33. // visible to sysadmin tools, use GetRegInteger instead.
  34. //
  35. // This function will only work on GOOS=windows. Trying to run it on any other
  36. // OS will always return 0 and ErrNoValue.
  37. // If value does not exist or another error happens, returns 0 and error.
  38. func GetPolicyInteger(name string) (uint64, error) {
  39. return getPolicyInteger(name)
  40. }
  41. // GetRegString looks up a registry path in the local machine path, or returns
  42. // an empty string and error.
  43. //
  44. // This function will only work on GOOS=windows. Trying to run it on any other
  45. // OS will always return an empty string and ErrNoValue.
  46. // If value does not exist or another error happens, returns empty string and error.
  47. func GetRegString(name string) (string, error) {
  48. return getRegString(name)
  49. }
  50. // GetRegInteger looks up a registry path in the local machine path, or returns
  51. // 0 and the error.
  52. //
  53. // This function will only work on GOOS=windows. Trying to run it on any other
  54. // OS will always return 0 and ErrNoValue.
  55. // If value does not exist or another error happens, returns 0 and error.
  56. func GetRegInteger(name string) (uint64, error) {
  57. return getRegInteger(name)
  58. }
  59. // IsSIDValidPrincipal determines whether the SID contained in uid represents a
  60. // type that is a valid security principal under Windows. This check helps us
  61. // work around a bug in the standard library's Windows implementation of
  62. // LookupId in os/user.
  63. // See https://github.com/tailscale/tailscale/issues/869
  64. //
  65. // This function will only work on GOOS=windows. Trying to run it on any other
  66. // OS will always return false.
  67. func IsSIDValidPrincipal(uid string) bool {
  68. return isSIDValidPrincipal(uid)
  69. }
  70. // LookupPseudoUser attempts to resolve the user specified by uid by checking
  71. // against well-known pseudo-users on Windows. This is a temporary workaround
  72. // until https://github.com/golang/go/issues/49509 is resolved and shipped.
  73. //
  74. // This function will only work on GOOS=windows. Trying to run it on any other
  75. // OS will always return an error.
  76. func LookupPseudoUser(uid string) (*user.User, error) {
  77. return lookupPseudoUser(uid)
  78. }
  79. // RegisterForRestartOpts supplies options to RegisterForRestart.
  80. type RegisterForRestartOpts struct {
  81. RestartOnCrash bool // When true, this program will be restarted after a crash.
  82. RestartOnHang bool // When true, this program will be restarted after a hang.
  83. RestartOnUpgrade bool // When true, this program will be restarted after an upgrade.
  84. RestartOnReboot bool // When true, this program will be restarted after a reboot.
  85. UseCmdLineArgs bool // When true, CmdLineArgs will be used as the program's arguments upon restart. Otherwise no arguments will be provided.
  86. CmdLineArgs []string // When UseCmdLineArgs == true, contains the command line arguments, excluding the executable name itself. If nil or empty, the arguments from the current process will be re-used.
  87. }
  88. // RegisterForRestart registers the current process' restart preferences with
  89. // the Windows Restart Manager. This enables the OS to intelligently restart
  90. // the calling executable as requested via opts. This should be called by any
  91. // programs which need to be restarted by the installer post-update.
  92. //
  93. // This function may be called multiple times; the opts from the most recent
  94. // call will override those from any previous invocations.
  95. //
  96. // This function will only work on GOOS=windows. Trying to run it on any other
  97. // OS will always return nil.
  98. func RegisterForRestart(opts RegisterForRestartOpts) error {
  99. return registerForRestart(opts)
  100. }