operatingsystem_windows.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"
  2. import (
  3. "errors"
  4. "github.com/Microsoft/hcsshim/osversion"
  5. "golang.org/x/sys/windows"
  6. "golang.org/x/sys/windows/registry"
  7. )
  8. // VER_NT_WORKSTATION, see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
  9. const verNTWorkstation = 0x00000001 // VER_NT_WORKSTATION
  10. // GetOperatingSystem gets the name of the current operating system.
  11. func GetOperatingSystem() (string, error) {
  12. osversion := windows.RtlGetVersion() // Always succeeds.
  13. rel := windowsOSRelease{
  14. IsServer: osversion.ProductType != verNTWorkstation,
  15. Build: osversion.BuildNumber,
  16. }
  17. // Make a best-effort attempt to retrieve the display version and
  18. // Update Build Revision by querying undocumented registry values.
  19. key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
  20. if err == nil {
  21. defer key.Close()
  22. if ver, err := getFirstStringValue(key,
  23. "DisplayVersion", /* Windows 20H2 and above */
  24. "ReleaseId", /* Windows 2009 and below */
  25. ); err == nil {
  26. rel.DisplayVersion = ver
  27. }
  28. if ubr, _, err := key.GetIntegerValue("UBR"); err == nil {
  29. rel.UBR = ubr
  30. }
  31. }
  32. return rel.String(), nil
  33. }
  34. func getFirstStringValue(key registry.Key, names ...string) (string, error) {
  35. for _, n := range names {
  36. val, _, err := key.GetStringValue(n)
  37. if err != nil {
  38. if !errors.Is(err, registry.ErrNotExist) {
  39. return "", err
  40. }
  41. continue
  42. }
  43. return val, nil
  44. }
  45. return "", registry.ErrNotExist
  46. }
  47. // GetOperatingSystemVersion gets the version of the current operating system, as a string.
  48. func GetOperatingSystemVersion() (string, error) {
  49. return osversion.Get().ToString(), nil
  50. }
  51. // IsContainerized returns true if we are running inside a container.
  52. // No-op on Windows, always returns false.
  53. func IsContainerized() (bool, error) {
  54. return false, nil
  55. }
  56. // IsWindowsClient returns true if the SKU is client. It returns false on
  57. // Windows server.
  58. func IsWindowsClient() bool {
  59. return windows.RtlGetVersion().ProductType == verNTWorkstation
  60. }