]> Cypherpunks repositories - gostls13.git/commitdiff
os: Use GetComputerNameEx to get Hostname on win32
authorCarlos Castillo <cookieo9@gmail.com>
Tue, 24 Feb 2015 10:35:55 +0000 (02:35 -0800)
committerAlex Brainman <alex.brainman@gmail.com>
Wed, 25 Feb 2015 23:16:44 +0000 (23:16 +0000)
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>
src/cmd/dist/build.go
src/go/build/deps_test.go
src/internal/syscall/windows/syscall_windows.go
src/internal/syscall/windows/zsyscall_windows.go
src/os/sys_windows.go

index c816ff751d7ce2dd487d5a7a18c0445efebf5d81..a9b4988a38b0f710cb01bf33dec4a1543a7986f6 100644 (file)
@@ -1140,6 +1140,7 @@ var buildorder = []string{
        "encoding/base64",
        "syscall",
        "time",
+       "internal/syscall/windows",
        "os",
        "reflect",
        "fmt",
index d186a17e0e92fe946355a4963c015790156c22a0..7076f43163e46a1a65ee4b9cc7523cf3178071b2 100644 (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"},
index 2541a83440196bf996b0743740f0ca1e3b4d99f2..49bfeea1f4ce346087bc9c063b9628fd5557108d 100644 (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
+)
index 90e203464110bc966231fd062cac4dd92166f756..50c7c5165b235c64a6f61ca8aeb7d2298d46a7c2 100644 (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
+}
index 92617de5e73d2b34014b5245d6d7e9cd6bc849ff..9490ea6c592a63401ebee65ec8a7481bed47aa18 100644 (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
 }