github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/version/osversion_windows.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package version
     5  
     6  import (
     7  	"strings"
     8  	"syscall"
     9  	"unsafe"
    10  
    11  	"github.com/juju/errors"
    12  )
    13  
    14  func readRegString(h syscall.Handle, key string) (value string, err error) {
    15  	var typ uint32
    16  	var buf uint32
    17  
    18  	// Get size of registry key
    19  	err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(key), nil, &typ, nil, &buf)
    20  	if err != nil {
    21  		return value, err
    22  	}
    23  
    24  	n := make([]uint16, buf/2+1)
    25  	err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(key), nil, &typ, (*byte)(unsafe.Pointer(&n[0])), &buf)
    26  	if err != nil {
    27  		return value, err
    28  	}
    29  	return syscall.UTF16ToString(n[:]), err
    30  }
    31  
    32  func getVersionFromRegistry() (string, error) {
    33  	var h syscall.Handle
    34  	err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
    35  		syscall.StringToUTF16Ptr("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
    36  		0, syscall.KEY_READ, &h)
    37  	if err != nil {
    38  		return "", err
    39  	}
    40  	defer syscall.RegCloseKey(h)
    41  	str, err := readRegString(h, "ProductName")
    42  	if err != nil {
    43  		return "", err
    44  	}
    45  	return str, nil
    46  }
    47  
    48  func osVersion() (string, error) {
    49  	ver, err := getVersionFromRegistry()
    50  	if err != nil {
    51  		return "unknown", err
    52  	}
    53  	if val, ok := windowsVersions[ver]; ok {
    54  		return val, nil
    55  	}
    56  	for key, value := range windowsVersions {
    57  		if strings.HasPrefix(ver, key) {
    58  			return value, nil
    59  		}
    60  	}
    61  	return "unknown", errors.Errorf("unknown series %q", ver)
    62  }