]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
wintun: rename device using undocumented API that netsh.exe uses
authorJason A. Donenfeld <Jason@zx2c4.com>
Mon, 1 Apr 2019 10:00:33 +0000 (12:00 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 1 Apr 2019 10:04:44 +0000 (12:04 +0200)
tun/wintun/netshell/netshell_windows.go [new file with mode: 0644]
tun/wintun/wintun_windows.go

diff --git a/tun/wintun/netshell/netshell_windows.go b/tun/wintun/netshell/netshell_windows.go
new file mode 100644 (file)
index 0000000..cb03252
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package netshell
+
+import (
+       "syscall"
+       "unsafe"
+
+       "golang.org/x/sys/windows"
+)
+
+var (
+       modnetshell = windows.NewLazySystemDLL("netshell.dll")
+       procHrRenameConnection = modnetshell.NewProc("HrRenameConnection")
+)
+
+func HrRenameConnection(guid *windows.GUID, newName *uint16) (err error) {
+       err = procHrRenameConnection.Find()
+       if err != nil {
+               // Missing from servercore, so we can't presume it's always there.
+               return
+       }
+
+       ret, _, _ := syscall.Syscall(procHrRenameConnection.Addr(), 2, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(newName)), 0)
+       if ret != 0 {
+               err = syscall.Errno(ret)
+       }
+       return
+}
index 77e83a0b3356017ff9e9cfe7f77b20d276793a6b..8e09c411b22cb6bbfd43e3b07fb78aaa1756d308 100644 (file)
@@ -8,6 +8,7 @@ package wintun
 import (
        "errors"
        "fmt"
+       "golang.zx2c4.com/wireguard/tun/wintun/netshell"
        "strings"
        "syscall"
        "time"
@@ -449,13 +450,20 @@ func (wintun *Wintun) GetInterfaceName() (string, error) {
 // SetInterfaceName sets network interface name.
 //
 func (wintun *Wintun) SetInterfaceName(ifname string) error {
+       // We open the registry key before calling HrRename, because the registry open will wait until the key exists.
        key, err := registryOpenKeyRetry(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.SET_VALUE)
        if err != nil {
                return errors.New("Network-specific registry key open failed: " + err.Error())
        }
        defer key.Close()
 
-       // Set the interface name.
+       // We have to tell the various runtime COM services about the new name too. We ignore the
+       // error because netshell isn't available on servercore.
+       // TODO: netsh.exe falls back to NciSetConnection in this case. If somebody complains, maybe
+       // we should do the same.
+       _ = netshell.HrRenameConnection(&wintun.CfgInstanceID, windows.StringToUTF16Ptr(ifname))
+
+       // Set the interface name. The above line should have done this too, but in case it failed, we force it.
        return key.SetStringValue("Name", ifname)
 }