1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/pkg/parsers/operatingsystem/operatingsystem_windows.go
Cory Snider 9aacaeb667 pkg/parsers: support Windows 11; drop ProductName
Microsoft has stopped updating the ProductName registry value in Windows
11; it reads as Windows 10. And Microsoft has made it very difficult to
look up the real product name programmatically so that applications do
not attempt to parse it. (Ever wonder why they skipped Windows 9?) The
only documented and supported mechanisms require WMI or WinRT. The
product name has no bearing on application compatibility so it is not
worth doing any heroics to display the correct name. The build number
and Update Build Revision is sufficient information to identify a
specific build of Windows. Stop displaying the ProductName so as not to
confuse users with incorrect information.

Microsoft has frozen the ReleaseId registry value at 2009 when they
switched to semi-annual releases and alpha-numeric versions. The release
version as displayed by winver.exe and Settings -> System -> About on
Windows 20H2 and newer can be found in the new DisplayVersion registry
value. Replicate the way winver.exe displays the version by
preferentially reporting the DisplayVersion if present and reporting if
it is a Windows Server edition.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-03-04 16:08:34 -05:00

64 lines
1.9 KiB
Go

package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"
import (
"errors"
"github.com/Microsoft/hcsshim/osversion"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
// VER_NT_WORKSTATION, see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
const verNTWorkstation = 0x00000001 // VER_NT_WORKSTATION
// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
osversion := windows.RtlGetVersion() // Always succeeds.
rel := windowsOSRelease{
IsServer: osversion.ProductType != verNTWorkstation,
Build: osversion.BuildNumber,
}
// Make a best-effort attempt to retrieve the display version and
// Update Build Revision by querying undocumented registry values.
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
if err == nil {
defer key.Close()
if ver, err := getFirstStringValue(key,
"DisplayVersion", /* Windows 20H2 and above */
"ReleaseId", /* Windows 2009 and below */
); err == nil {
rel.DisplayVersion = ver
}
if ubr, _, err := key.GetIntegerValue("UBR"); err == nil {
rel.UBR = ubr
}
}
return rel.String(), nil
}
func getFirstStringValue(key registry.Key, names ...string) (string, error) {
for _, n := range names {
val, _, err := key.GetStringValue(n)
if err != nil {
if !errors.Is(err, registry.ErrNotExist) {
return "", err
}
continue
}
return val, nil
}
return "", registry.ErrNotExist
}
// GetOperatingSystemVersion gets the version of the current operating system, as a string.
func GetOperatingSystemVersion() (string, error) {
return osversion.Get().ToString(), nil
}
// IsContainerized returns true if we are running inside a container.
// No-op on Windows, always returns false.
func IsContainerized() (bool, error) {
return false, nil
}