aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tun/tun_windows.go4
-rw-r--r--tun/wintun/wintun_windows.go133
2 files changed, 79 insertions, 58 deletions
diff --git a/tun/tun_windows.go b/tun/tun_windows.go
index 8c384f6..7051d61 100644
--- a/tun/tun_windows.go
+++ b/tun/tun_windows.go
@@ -67,7 +67,7 @@ func CreateTUN(ifname string) (TUNDevice, error) {
wt, err = wintun.GetInterface(ifname, 0)
if err == nil {
// If so, we delete it, in case it has weird residual configuration.
- _, _, err = wt.DeleteInterface(0)
+ _, err = wt.DeleteInterface(0)
if err != nil {
return nil, fmt.Errorf("Unable to delete already existing Wintun interface: %v", err)
}
@@ -206,7 +206,7 @@ func (tun *NativeTun) Close() error {
close(tun.events)
}
- _, _, err2 := tun.wt.DeleteInterface(0)
+ _, err2 := tun.wt.DeleteInterface(0)
if err1 == nil {
err1 = err2
}
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index f962f6e..3d41f38 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -417,71 +417,41 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
// optional and can be 0. If a specific top-level window is not required, set
// hwndParent to 0.
//
-// Function returns true if the interface was found and deleted and a flag if
-// reboot is required.
+// Function silently succeeds if the interface was not found.
//
-func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, bool, error) {
- // Create a list of network devices.
- devInfoList, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, enumerator, hwndParent, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), machineName)
+// Function returns true if a reboot is required.
+//
+func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, error) {
+ devInfoList, deviceData, err := wintun.deviceData(hwndParent)
+ if err == windows.ERROR_OBJECT_NOT_FOUND {
+ return false, nil
+ }
if err != nil {
- return false, false, fmt.Errorf("SetupDiGetClassDevsEx(%s) failed: %v", guid.ToString(&deviceClassNetGUID), err.Error())
+ return false, err
}
defer devInfoList.Close()
- // Iterate.
- for index := 0; ; index++ {
- // Get the device from the list. Should anything be wrong with this device, continue with next.
- deviceData, err := devInfoList.EnumDeviceInfo(index)
- if err != nil {
- if errWin, ok := err.(windows.Errno); ok && errWin == windows.ERROR_NO_MORE_ITEMS {
- break
- }
- continue
- }
-
- // Get interface ID.
- //TODO: Store some ID in the Wintun object such that this call isn't required.
- wintun2, err := makeWintun(devInfoList, deviceData)
- if err != nil {
- continue
- }
-
- if wintun.cfgInstanceID == wintun2.cfgInstanceID {
- if hwndParent == 0 {
- err = setQuietInstall(devInfoList, deviceData)
- if err != nil {
- return false, false, fmt.Errorf("Setting quiet installation failed: %v", err)
- }
- }
-
- // Remove the device.
- removeDeviceParams := setupapi.RemoveDeviceParams{
- ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE),
- Scope: setupapi.DI_REMOVEDEVICE_GLOBAL,
- }
-
- // Set class installer parameters for DIF_REMOVE.
- err = devInfoList.SetClassInstallParams(deviceData, &removeDeviceParams.ClassInstallHeader, uint32(unsafe.Sizeof(removeDeviceParams)))
- if err != nil {
- return false, false, fmt.Errorf("SetupDiSetClassInstallParams failed: %v", err)
- }
-
- // Call appropriate class installer.
- err = devInfoList.CallClassInstaller(setupapi.DIF_REMOVE, deviceData)
- if err != nil {
- return false, false, fmt.Errorf("SetupDiCallClassInstaller failed: %v", err)
- }
+ // Remove the device.
+ removeDeviceParams := setupapi.RemoveDeviceParams{
+ ClassInstallHeader: *setupapi.MakeClassInstallHeader(setupapi.DIF_REMOVE),
+ Scope: setupapi.DI_REMOVEDEVICE_GLOBAL,
+ }
- // Check if a system reboot is required. (Ignore errors)
- if ret, _ := checkReboot(devInfoList, deviceData); ret {
- return true, true, nil
- }
+ // Set class installer parameters for DIF_REMOVE.
+ err = devInfoList.SetClassInstallParams(deviceData, &removeDeviceParams.ClassInstallHeader, uint32(unsafe.Sizeof(removeDeviceParams)))
+ if err != nil {
+ return false, fmt.Errorf("SetupDiSetClassInstallParams failed: %v", err)
+ }
- return true, false, nil
- }
+ // Call appropriate class installer.
+ err = devInfoList.CallClassInstaller(setupapi.DIF_REMOVE, deviceData)
+ if err != nil {
+ return false, fmt.Errorf("SetupDiCallClassInstaller failed: %v", err)
}
- return false, false, nil
+ // Check if a system reboot is required. (Ignore errors)
+ ret, _ := checkReboot(devInfoList, deviceData)
+ return ret, nil
}
//
@@ -576,6 +546,57 @@ func (wintun *Wintun) tcpipInterfaceRegKeyName() (path string, err error) {
}
//
+// deviceData returns TUN device info list handle and interface device info
+// data.
+//
+// The device info list handle must be closed after use.
+//
+// In case the device is not found, windows.ERROR_OBJECT_NOT_FOUND is
+// returned.
+//
+func (wintun *Wintun) deviceData(hwndParent uintptr) (setupapi.DevInfo, *setupapi.DevInfoData, error) {
+ // Create a list of network devices.
+ devInfoList, err := setupapi.SetupDiGetClassDevsEx(&deviceClassNetGUID, enumerator, hwndParent, setupapi.DIGCF_PRESENT, setupapi.DevInfo(0), machineName)
+ if err != nil {
+ return 0, nil, fmt.Errorf("SetupDiGetClassDevsEx(%s) failed: %v", guid.ToString(&deviceClassNetGUID), err.Error())
+ }
+
+ // Iterate.
+ for index := 0; ; index++ {
+ // Get the device from the list. Should anything be wrong with this device, continue with next.
+ deviceData, err := devInfoList.EnumDeviceInfo(index)
+ if err != nil {
+ if errWin, ok := err.(windows.Errno); ok && errWin == windows.ERROR_NO_MORE_ITEMS {
+ break
+ }
+ continue
+ }
+
+ // Get interface ID.
+ //TODO: Store some ID in the Wintun object such that this call isn't required.
+ wintun2, err := makeWintun(devInfoList, deviceData)
+ if err != nil {
+ continue
+ }
+
+ if wintun.cfgInstanceID == wintun2.cfgInstanceID {
+ if hwndParent == 0 {
+ err = setQuietInstall(devInfoList, deviceData)
+ if err != nil {
+ devInfoList.Close()
+ return 0, nil, fmt.Errorf("Setting quiet installation failed: %v", err)
+ }
+ }
+
+ return devInfoList, deviceData, nil
+ }
+ }
+
+ devInfoList.Close()
+ return 0, nil, windows.ERROR_OBJECT_NOT_FOUND
+}
+
+//
// DataFileName returns Wintun device data pipe name.
//
func (wintun *Wintun) DataFileName() string {