1
0
mirror of https://github.com/golang/go synced 2024-11-05 11:36:10 -07:00

os: Use GetComputerNameEx to get Hostname on win32

The existing Hostname function uses the GetComputerName system
function in windows to determine the hostname. It has some downsides:

  - The name is limited to 15 characters.
  - The name returned is for NetBIOS, other OS's return a DNS name

This change adds to the internal/syscall/windows package a
GetComputerNameEx function, and related enum constants. They are used
instead of the syscall.ComputerName function to implement os.Hostname
on windows.

Fixes #9982

Change-Id: Idc8782785eb1eea37e64022bd201699ce9c4b39c
Reviewed-on: https://go-review.googlesource.com/5852
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Carlos Castillo <cookieo9@gmail.com>
Reviewed-by: Yasuhiro MATSUMOTO <mattn.jp@gmail.com>
This commit is contained in:
Carlos Castillo 2015-02-24 02:35:55 -08:00 committed by Alex Brainman
parent ca0be6f849
commit 59e546633d
5 changed files with 56 additions and 9 deletions

View File

@ -1140,6 +1140,7 @@ var buildorder = []string{
"encoding/base64",
"syscall",
"time",
"internal/syscall/windows",
"os",
"reflect",
"fmt",

View File

@ -123,7 +123,7 @@ var pkgDeps = map[string][]string{
// Operating system access.
"syscall": {"L0", "unicode/utf16"},
"time": {"L0", "syscall"},
"os": {"L1", "os", "syscall", "time"},
"os": {"L1", "os", "syscall", "time", "internal/syscall/windows"},
"path/filepath": {"L2", "os", "syscall"},
"io/ioutil": {"L2", "os", "path/filepath", "time"},
"os/exec": {"L2", "os", "path/filepath", "syscall"},

View File

@ -4,9 +4,7 @@
package windows
import (
"syscall"
)
import "syscall"
//go:generate go run ../../../syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
@ -97,3 +95,17 @@ const (
)
//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizeOfPointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
//sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
const (
ComputerNameNetBIOS = 0
ComputerNameDnsHostname = 1
ComputerNameDnsDomain = 2
ComputerNameDnsFullyQualified = 3
ComputerNamePhysicalNetBIOS = 4
ComputerNamePhysicalDnsHostname = 5
ComputerNamePhysicalDnsDomain = 6
ComputerNamePhysicalDnsFullyQualified = 7
ComputerNameMax = 8
)

View File

@ -5,10 +5,14 @@ package windows
import "unsafe"
import "syscall"
var _ unsafe.Pointer
var (
modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
)
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizeOfPointer *uint32) (errcode error) {
@ -18,3 +22,15 @@ func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapter
}
return
}
func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}

View File

@ -4,12 +4,30 @@
package os
import "syscall"
import (
"internal/syscall/windows"
"syscall"
)
func hostname() (name string, err error) {
s, e := syscall.ComputerName()
if e != nil {
return "", NewSyscallError("ComputerName", e)
// Use PhysicalDnsHostname to uniquely identify host in a cluster
const format = windows.ComputerNamePhysicalDnsHostname
n := uint32(64)
for {
b := make([]uint16, n)
err := windows.GetComputerNameEx(format, &b[0], &n)
if err == nil {
return syscall.UTF16ToString(b[:n]), nil
}
if err != syscall.ERROR_MORE_DATA {
return "", NewSyscallError("ComputerNameEx", err)
}
// If we received a ERROR_MORE_DATA, but n doesn't get larger,
// something has gone wrong and we may be in an infinite loop
if n <= uint32(len(b)) {
return "", NewSyscallError("ComputerNameEx", err)
}
}
return s, nil
}