]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
tun: windows: Adapter devices renamed to WINTUN<LUID Index>
authorSimon Rozman <simon@rozman.si>
Fri, 22 Mar 2019 14:28:33 +0000 (15:28 +0100)
committerSimon Rozman <simon@rozman.si>
Fri, 22 Mar 2019 14:29:14 +0000 (15:29 +0100)
Signed-off-by: Simon Rozman <simon@rozman.si>
tun/tun_windows.go
tun/wintun/setupapi/setupapi_windows.go
tun/wintun/setupapi/setupapi_windows_test.go
tun/wintun/wintun_windows.go

index d4be66b47c12cc79f6fb21c415258b8eba15cb68..42231905325a0f0b192cebcf516641d0b72432ec 100644 (file)
@@ -348,5 +348,5 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
 // GUID returns Windows adapter instance ID.
 //
 func (tun *NativeTun) GUID() windows.GUID {
-       return *(*windows.GUID)(tun.wt)
+       return tun.wt.CfgInstanceID
 }
index 486a1ffcf71fe1f40f82532d530ff86aef36404b..71732a40e2ac88f5563e7c544c7f1bf523c2fcab 100644 (file)
@@ -7,14 +7,12 @@ package setupapi
 
 import (
        "encoding/binary"
-       "errors"
        "fmt"
        "syscall"
        "unsafe"
 
        "golang.org/x/sys/windows"
        "golang.org/x/sys/windows/registry"
-       "golang.zx2c4.com/wireguard/tun/wintun/guid"
 )
 
 //sys  setupDiCreateDeviceInfoListEx(classGUID *windows.GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) [failretval==DevInfo(windows.InvalidHandle)] = setupapi.SetupDiCreateDeviceInfoListExW
@@ -236,33 +234,6 @@ func (deviceInfoSet DevInfo) OpenDevRegKey(DeviceInfoData *DevInfoData, Scope DI
        return SetupDiOpenDevRegKey(deviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired)
 }
 
-// GetInterfaceID method returns network interface ID.
-func (deviceInfoSet DevInfo) GetInterfaceID(deviceInfoData *DevInfoData) (*windows.GUID, error) {
-       // Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key.
-       key, err := deviceInfoSet.OpenDevRegKey(deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, registry.READ)
-       if err != nil {
-               return nil, errors.New("Device-specific registry key open failed: " + err.Error())
-       }
-       defer key.Close()
-
-       // Read the NetCfgInstanceId value.
-       value, valueType, err := key.GetStringValue("NetCfgInstanceId")
-       if err != nil {
-               return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error())
-       }
-       if valueType != registry.SZ {
-               return nil, fmt.Errorf("NetCfgInstanceId registry value is not REG_SZ (expected: %v, provided: %v)", registry.SZ, valueType)
-       }
-
-       // Convert to windows.GUID.
-       ifid, err := guid.FromString(value)
-       if err != nil {
-               return nil, fmt.Errorf("NetCfgInstanceId registry value is not a GUID (expected: \"{...}\", provided: %q)", value)
-       }
-
-       return ifid, nil
-}
-
 //sys  setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDeviceRegistryPropertyW
 
 // SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
index c6f4a1552ada171373467aa7c059049aedc5af13..30f36920d3bf6e0ae894e577ab6d1e1a48231c7d 100644 (file)
@@ -291,11 +291,6 @@ func TestSetupDiOpenDevRegKey(t *testing.T) {
                        t.Errorf("Error calling SetupDiOpenDevRegKey: %s", err.Error())
                }
                defer key.Close()
-
-               _, err = devInfoList.GetInterfaceID(data)
-               if err != nil {
-                       t.Errorf("Error calling GetInterfaceID: %s", err.Error())
-               }
        }
 }
 
index 881b656f3d808be13c65ca9d0a9da89102a6fab0..7170686394386787d4788818c7dcca8ea11a6c80 100644 (file)
@@ -22,7 +22,11 @@ import (
 //
 // Wintun is a handle of a Wintun adapter
 //
-type Wintun windows.GUID
+type Wintun struct {
+       CfgInstanceID windows.GUID
+       LUIDIndex     uint32
+       IfType        uint32
+}
 
 var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}
 
@@ -31,7 +35,52 @@ const enumerator = ""
 const machineName = ""
 
 //
-// GetInterface finds interface ID by name.
+// MakeWintun creates interface handle and populates it from device registry key
+//
+func MakeWintun(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfoData) (*Wintun, error) {
+       // Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key.
+       key, err := deviceInfoSet.OpenDevRegKey(deviceInfoData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.READ)
+       if err != nil {
+               return nil, errors.New("Device-specific registry key open failed: " + err.Error())
+       }
+       defer key.Close()
+
+       // Read the NetCfgInstanceId value.
+       valueStr, valueType, err := key.GetStringValue("NetCfgInstanceId")
+       if err != nil {
+               return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error())
+       }
+       if valueType != registry.SZ {
+               return nil, fmt.Errorf("NetCfgInstanceId registry value is not REG_SZ (expected: %v, provided: %v)", registry.SZ, valueType)
+       }
+
+       // Convert to windows.GUID.
+       ifid, err := guid.FromString(valueStr)
+       if err != nil {
+               return nil, fmt.Errorf("NetCfgInstanceId registry value is not a GUID (expected: \"{...}\", provided: %q)", valueStr)
+       }
+
+       // Read the NetLuidIndex value.
+       luidIdx, valueType, err := key.GetIntegerValue("NetLuidIndex")
+       if err != nil {
+               return nil, errors.New("RegQueryValue(\"NetLuidIndex\") failed: " + err.Error())
+       }
+
+       // Read the NetLuidIndex value.
+       ifType, valueType, err := key.GetIntegerValue("*IfType")
+       if err != nil {
+               return nil, errors.New("RegQueryValue(\"*IfType\") failed: " + err.Error())
+       }
+
+       return &Wintun{
+               CfgInstanceID: *ifid,
+               LUIDIndex:     uint32(luidIdx),
+               IfType:        uint32(ifType),
+       }, nil
+}
+
+//
+// GetInterface finds interface by name.
 //
 // 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-
@@ -39,9 +88,8 @@ const machineName = ""
 // optional and can be 0. If a specific top-level window is not required, set
 // hwndParent to 0.
 //
-// Function returns interface ID when the interface was found, or nil
-// otherwise. If the interface is found but not Wintun-class, the function
-// returns interface ID with an error.
+// Function returns interface if found, or nil otherwise. If the interface is
+// found but not Wintun-class, the function returns interface and an error.
 //
 func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
        // Create a list of network devices.
@@ -70,13 +118,13 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
                }
 
                // Get interface ID.
-               ifid, err := devInfoList.GetInterfaceID(deviceData)
+               wintun, err := MakeWintun(devInfoList, deviceData)
                if err != nil {
                        continue
                }
 
                // Get interface name.
-               ifname2, err := ((*Wintun)(ifid)).GetInterfaceName()
+               ifname2, err := wintun.GetInterfaceName()
                if err != nil {
                        continue
                }
@@ -110,12 +158,12 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
 
                                if driverDetailData.IsCompatible(hardwareID) {
                                        // Matching hardware ID found.
-                                       return (*Wintun)(ifid), nil
+                                       return wintun, nil
                                }
                        }
 
                        // This interface is not using Wintun driver.
-                       return (*Wintun)(ifid), errors.New("Foreign network interface with the same name exists")
+                       return wintun, errors.New("Foreign network interface with the same name exists")
                }
        }
 
@@ -273,7 +321,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
                                return nil, fmt.Errorf("NetCfgInstanceId registry value is not a GUID (expected: \"{...}\", provided: %q)", value)
                        }
 
-                       wintun := (*Wintun)(ifid)
+                       wintun := &Wintun{CfgInstanceID: *ifid}
                        keyNetName := wintun.GetNetRegKeyName()
                        keyNet, err := registry.OpenKey(registry.LOCAL_MACHINE, keyNetName, registry.QUERY_VALUE)
                        if err != nil {
@@ -355,8 +403,6 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
 // reboot is required.
 //
 func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, bool, error) {
-       ifid := (*windows.GUID)(wintun)
-
        // Create a list of network devices.
        devInfoList, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, enumerator, hwndParent, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), machineName)
        if err != nil {
@@ -376,12 +422,12 @@ func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, bool, error) {
                }
 
                // Get interface ID.
-               ifid2, err := devInfoList.GetInterfaceID(deviceData)
+               wintun2, err := MakeWintun(devInfoList, deviceData)
                if err != nil {
                        continue
                }
 
-               if *ifid == *ifid2 {
+               if wintun.CfgInstanceID == wintun2.CfgInstanceID {
                        // Remove the device.
                        removeDeviceParams := setupapi.RemoveDeviceParams{
                                ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE),
@@ -469,8 +515,7 @@ func (wintun *Wintun) SetInterfaceName(ifname string) error {
 // GetNetRegKeyName returns interface-specific network registry key name.
 //
 func (wintun *Wintun) GetNetRegKeyName() string {
-       ifid := (*windows.GUID)(wintun)
-       return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Control\\Network\\%v\\%v\\Connection", guid.ToString(&deviceClassNetGUID), guid.ToString(ifid))
+       return fmt.Sprintf("SYSTEM\\CurrentControlSet\\Control\\Network\\%v\\%v\\Connection", guid.ToString(&deviceClassNetGUID), guid.ToString(&wintun.CfgInstanceID))
 }
 
 //
@@ -505,5 +550,5 @@ func getRegStringValue(key registry.Key, name string) (string, error) {
 // DataFileName returns Wintun device data pipe name.
 //
 func (wintun *Wintun) DataFileName() string {
-       return fmt.Sprintf("\\\\.\\Global\\WINTUN_DEVICE_%s", guid.ToString((*windows.GUID)(wintun)))
+       return fmt.Sprintf("\\\\.\\Global\\WINTUN%d", wintun.LUIDIndex)
 }