github.com/ph/moby@v1.13.1/pkg/parsers/kernel/kernel_windows.go (about)

     1  // +build windows
     2  
     3  package kernel
     4  
     5  import (
     6  	"fmt"
     7  	"syscall"
     8  	"unsafe"
     9  )
    10  
    11  // VersionInfo holds information about the kernel.
    12  type VersionInfo struct {
    13  	kvi   string // Version of the kernel (e.g. 6.1.7601.17592 -> 6)
    14  	major int    // Major part of the kernel version (e.g. 6.1.7601.17592 -> 1)
    15  	minor int    // Minor part of the kernel version (e.g. 6.1.7601.17592 -> 7601)
    16  	build int    // Build number of the kernel version (e.g. 6.1.7601.17592 -> 17592)
    17  }
    18  
    19  func (k *VersionInfo) String() string {
    20  	return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
    21  }
    22  
    23  // GetKernelVersion gets the current kernel version.
    24  func GetKernelVersion() (*VersionInfo, error) {
    25  
    26  	var (
    27  		h         syscall.Handle
    28  		dwVersion uint32
    29  		err       error
    30  	)
    31  
    32  	KVI := &VersionInfo{"Unknown", 0, 0, 0}
    33  
    34  	if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
    35  		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
    36  		0,
    37  		syscall.KEY_READ,
    38  		&h); err != nil {
    39  		return KVI, err
    40  	}
    41  	defer syscall.RegCloseKey(h)
    42  
    43  	var buf [1 << 10]uint16
    44  	var typ uint32
    45  	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
    46  
    47  	if err = syscall.RegQueryValueEx(h,
    48  		syscall.StringToUTF16Ptr("BuildLabEx"),
    49  		nil,
    50  		&typ,
    51  		(*byte)(unsafe.Pointer(&buf[0])),
    52  		&n); err != nil {
    53  		return KVI, err
    54  	}
    55  
    56  	KVI.kvi = syscall.UTF16ToString(buf[:])
    57  
    58  	// Important - docker.exe MUST be manifested for this API to return
    59  	// the correct information.
    60  	if dwVersion, err = syscall.GetVersion(); err != nil {
    61  		return KVI, err
    62  	}
    63  
    64  	KVI.major = int(dwVersion & 0xFF)
    65  	KVI.minor = int((dwVersion & 0XFF00) >> 8)
    66  	KVI.build = int((dwVersion & 0xFFFF0000) >> 16)
    67  
    68  	return KVI, nil
    69  }