kernel_windows.go 1.3 KB

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