]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
wintun: allow controlling GUID
authorJason A. Donenfeld <Jason@zx2c4.com>
Sun, 9 Jun 2019 17:20:17 +0000 (19:20 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Mon, 10 Jun 2019 08:43:02 +0000 (10:43 +0200)
tun/tun_windows.go
tun/wintun/wintun_windows.go

index 0b41be9db85ff46b6ee6509cadc9819fe5f2dbed..1881e5bffff8a8b5d9252c98c0135750e962bf25 100644 (file)
@@ -60,6 +60,14 @@ func packetAlign(size uint32) uint32 {
 // adapter with the same name exist, it is reused.
 //
 func CreateTUN(ifname string) (TUNDevice, error) {
+       return CreateTUNWithRequestedGUID(ifname, nil)
+}
+
+//
+// CreateTUNWithRequestedGUID creates a Wintun adapter with the given name and
+// a requested GUID. Should a Wintun adapter with the same name exist, it is reused.
+//
+func CreateTUNWithRequestedGUID(ifname string, requestedGUID *windows.GUID) (TUNDevice, error) {
        var err error
        var wt *wintun.Wintun
 
@@ -74,7 +82,7 @@ func CreateTUN(ifname string) (TUNDevice, error) {
        } else if err == windows.ERROR_ALREADY_EXISTS {
                return nil, fmt.Errorf("Foreign network interface with the same name exists")
        }
-       wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
+       wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", requestedGUID, 0)
        if err != nil {
                return nil, fmt.Errorf("Unable to create Wintun interface: %v", err)
        }
index ec7f8eaaa23f88184d27b225f0b3ac7333d39a40..9e715818b94ea98f8e091dd22f68f50ff1bc41b9 100644 (file)
@@ -176,6 +176,13 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
 // description is a string that supplies the text description of the device.
 // description is optional and can be "".
 //
+// requestedGUID is the GUID of the created network interface, which then
+// influences NLA generation deterministically. If it is set to nil, the GUID
+// is chosen by the system at random, and hence a new NLA entry is created for
+// each new interface. It is called "requested" GUID because the API it uses
+// is completely undocumented, and so there could be minor interesting
+// complications with its usage.
+//
 // hwndParent is a handle to the top-level window to use for any user
 // interface that is related to non-device-specific actions (such as a select-
 // device dialog box that uses the global class driver list). This handle is
@@ -184,7 +191,7 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
 //
 // Function returns the network interface ID and a flag if reboot is required.
 //
-func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, error) {
+func CreateInterface(description string, requestedGUID *windows.GUID, hwndParent uintptr) (*Wintun, bool, error) {
        // Create an empty device info set for network adapter device class.
        devInfoList, err := setupapi.SetupDiCreateDeviceInfoListEx(&deviceClassNetGUID, hwndParent, machineName)
        if err != nil {
@@ -280,6 +287,18 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
        // Register device co-installers if any. (Ignore errors)
        devInfoList.CallClassInstaller(setupapi.DIF_REGISTER_COINSTALLERS, deviceData)
 
+       if requestedGUID != nil {
+               key, err := devInfoList.OpenDevRegKey(deviceData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.SET_VALUE)
+               if err != nil {
+                       return nil, false, fmt.Errorf("OpenDevRegKey failed: %v", err)
+               }
+               err = key.SetStringValue("NetSetupAnticipatedInstanceId", requestedGUID.String())
+               key.Close()
+               if err != nil {
+                       return nil, false, fmt.Errorf("SetStringValue(NetSetupAnticipatedInstanceId) failed: %v", err)
+               }
+       }
+
        // Install interfaces if any. (Ignore errors)
        devInfoList.CallClassInstaller(setupapi.DIF_INSTALLINTERFACES, deviceData)