pkg/system/syscall_windows.go
a7e686a7
 package system
 
805dd0ee
 import (
9c4570a9
 	"unsafe"
ef2db56b
 
 	"github.com/Sirupsen/logrus"
069fdc8a
 	"golang.org/x/sys/windows"
805dd0ee
 )
 
194eaa5c
 var (
069fdc8a
 	ntuserApiset       = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
75f7f2a8
 	procGetVersionExW  = modkernel32.NewProc("GetVersionExW")
 	procGetProductInfo = modkernel32.NewProc("GetProductInfo")
194eaa5c
 )
 
805dd0ee
 // OSVersion is a wrapper for Windows version information
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
 type OSVersion struct {
 	Version      uint32
 	MajorVersion uint8
 	MinorVersion uint8
 	Build        uint16
 }
 
ef2db56b
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
 type osVersionInfoEx struct {
 	OSVersionInfoSize uint32
 	MajorVersion      uint32
 	MinorVersion      uint32
 	BuildNumber       uint32
 	PlatformID        uint32
 	CSDVersion        [128]uint16
 	ServicePackMajor  uint16
 	ServicePackMinor  uint16
 	SuiteMask         uint16
 	ProductType       byte
 	Reserve           byte
 }
 
805dd0ee
 // GetOSVersion gets the operating system version on Windows. Note that
 // docker.exe must be manifested to get the correct version information.
194eaa5c
 func GetOSVersion() OSVersion {
805dd0ee
 	var err error
 	osv := OSVersion{}
069fdc8a
 	osv.Version, err = windows.GetVersion()
805dd0ee
 	if err != nil {
194eaa5c
 		// GetVersion never fails.
 		panic(err)
805dd0ee
 	}
 	osv.MajorVersion = uint8(osv.Version & 0xFF)
 	osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF)
 	osv.Build = uint16(osv.Version >> 16)
194eaa5c
 	return osv
805dd0ee
 }
 
ef2db56b
 // IsWindowsClient returns true if the SKU is client
87ab13ad
 // @engine maintainers - this function should not be removed or modified as it
 // is used to enforce licensing restrictions on Windows.
ef2db56b
 func IsWindowsClient() bool {
 	osviex := &osVersionInfoEx{OSVersionInfoSize: 284}
 	r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex)))
d0b9c33f
 	if r1 == 0 {
ef2db56b
 		logrus.Warnf("GetVersionExW failed - assuming server SKU: %v", err)
 		return false
 	}
 	const verNTWorkstation = 0x00000001
 	return osviex.ProductType == verNTWorkstation
 }
 
75f7f2a8
 // IsIoTCore returns true if the currently running image is based off of
 // Windows 10 IoT Core.
 // @engine maintainers - this function should not be removed or modified as it
 // is used to enforce licensing restrictions on Windows.
 func IsIoTCore() bool {
 	var returnedProductType uint32
 	r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType)))
 	if r1 == 0 {
 		logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err)
 		return false
 	}
 	const productIoTUAP = 0x0000007B
 	const productIoTUAPCommercial = 0x00000083
 	return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial
 }
 
853f2e99
 // Unmount is a platform-specific helper function to call
a7e686a7
 // the unmount syscall. Not supported on Windows
a20fea18
 func Unmount(dest string) error {
 	return nil
a7e686a7
 }
9c4570a9
 
 // CommandLineToArgv wraps the Windows syscall to turn a commandline into an argument array.
 func CommandLineToArgv(commandLine string) ([]string, error) {
 	var argc int32
 
069fdc8a
 	argsPtr, err := windows.UTF16PtrFromString(commandLine)
9c4570a9
 	if err != nil {
 		return nil, err
 	}
 
069fdc8a
 	argv, err := windows.CommandLineToArgv(argsPtr, &argc)
9c4570a9
 	if err != nil {
 		return nil, err
 	}
069fdc8a
 	defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv))))
9c4570a9
 
 	newArgs := make([]string, argc)
 	for i, v := range (*argv)[:argc] {
069fdc8a
 		newArgs[i] = string(windows.UTF16ToString((*v)[:]))
9c4570a9
 	}
 
 	return newArgs, nil
 }
194eaa5c
 
 // HasWin32KSupport determines whether containers that depend on win32k can
 // run on this machine. Win32k is the driver used to implement windowing.
 func HasWin32KSupport() bool {
 	// For now, check for ntuser API support on the host. In the future, a host
 	// may support win32k in containers even if the host does not support ntuser
 	// APIs.
 	return ntuserApiset.Load() == nil
 }