diff --git a/host/host_windows.go b/host/host_windows.go index 6fe6142..123eddf 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -16,7 +16,6 @@ import ( "github.com/shirou/gopsutil/internal/common" process "github.com/shirou/gopsutil/process" "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" ) var ( @@ -94,6 +93,8 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { } func getMachineGuid() (string, error) { + // there has been reports of issues on 32bit using golang.org/x/sys/windows/registry, see https://github.com/shirou/gopsutil/pull/312#issuecomment-277422612 + // for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue var h windows.Handle err := windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h) if err != nil { @@ -180,21 +181,34 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil } // Platform - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + var h windows.Handle // like getMachineGuid(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx + err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h) if err != nil { return } - defer k.Close() - platform, _, err = k.GetStringValue("ProductName") + defer windows.RegCloseKey(h) + var bufLen uint32 + var valType uint32 + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, nil, &bufLen) if err != nil { return } + regBuf := make([]uint16, bufLen/2+1) + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) + if err != nil { + return + } + platform = windows.UTF16ToString(regBuf[:]) if !strings.HasPrefix(platform, "Microsoft") { platform = "Microsoft " + platform } - csd, _, err := k.GetStringValue("CSDVersion") - if err == nil { - platform += " " + csd + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`CSDVersion`), nil, &valType, nil, &bufLen) // append Service Pack number, only on success + if err == nil { // don't return an error if only the Service Pack retrieval fails + regBuf = make([]uint16, bufLen/2+1) + err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`CSDVersion`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) + if err == nil { + platform += " " + windows.UTF16ToString(regBuf[:]) + } } // PlatformFamily @@ -210,7 +224,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil // Platform Version version = fmt.Sprintf("%d.%d.%d Build %d", osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber, osInfo.dwBuildNumber) - return + return platform, family, version, nil } func Users() ([]UserStat, error) {