diff --git a/tun/tun_windows.go b/tun/tun_windows.go index e2752db..4c48af5 100644 --- a/tun/tun_windows.go +++ b/tun/tun_windows.go @@ -52,6 +52,10 @@ func packetAlign(size uint32) uint32 { return (size + (packetExchangeAlignment - 1)) &^ (packetExchangeAlignment - 1) } +// +// CreateTUN creates a Wintun adapter with the given name. Should a Wintun +// adapter with the same name exist, it is reused. +// func CreateTUN(ifname string) (TUNDevice, error) { // Does an interface with this name already exist? wt, err := wintun.GetInterface(ifname, 0) @@ -351,6 +355,9 @@ func (tun *NativeTun) Write(buff []byte, offset int) (int, error) { return len(buff) - offset, tun.flush() } +// +// GUID returns Windows adapter instance ID. +// func (tun *NativeTun) GUID() windows.GUID { return *(*windows.GUID)(tun.wt) } diff --git a/tun/wintun/setupapi/setupapi_windows.go b/tun/wintun/setupapi/setupapi_windows.go index f736af5..71732a4 100644 --- a/tun/wintun/setupapi/setupapi_windows.go +++ b/tun/wintun/setupapi/setupapi_windows.go @@ -398,10 +398,10 @@ func SetupDiClassNameFromGuidEx(classGUID *windows.GUID, machineName string) (cl //sys setupDiClassGuidsFromNameEx(className *uint16, classGuidList *windows.GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) = setupapi.SetupDiClassGuidsFromNameExW // SetupDiClassGuidsFromNameEx function retrieves the GUIDs associated with the specified class name. This resulting list contains the classes currently installed on a local or remote computer. -func SetupDiClassGuidsFromNameEx(className string, machineName string) (classGuidLists []windows.GUID, err error) { +func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]windows.GUID, error) { classNameUTF16, err := syscall.UTF16PtrFromString(className) if err != nil { - return + return nil, err } const bufCapacity = 4 @@ -412,7 +412,7 @@ func SetupDiClassGuidsFromNameEx(className string, machineName string) (classGui if machineName != "" { machineNameUTF16, err = syscall.UTF16PtrFromString(machineName) if err != nil { - return + return nil, err } } @@ -431,7 +431,7 @@ func SetupDiClassGuidsFromNameEx(className string, machineName string) (classGui } } - return + return nil, err } //sys setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice diff --git a/tun/wintun/setupapi/setupapi_windows_test.go b/tun/wintun/setupapi/setupapi_windows_test.go index cec95d5..30f3692 100644 --- a/tun/wintun/setupapi/setupapi_windows_test.go +++ b/tun/wintun/setupapi/setupapi_windows_test.go @@ -10,11 +10,11 @@ import ( "syscall" "testing" - "golang.zx2c4.com/wireguard/tun/wintun/guid" "golang.org/x/sys/windows" + "golang.zx2c4.com/wireguard/tun/wintun/guid" ) -var deviceClassNetGUID = windows.GUID{0x4d36e972, 0xe325, 0x11ce, [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}} +var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}} var computerName string func init() { diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go index bb44963..85d29f4 100644 --- a/tun/wintun/wintun_windows.go +++ b/tun/wintun/wintun_windows.go @@ -19,11 +19,14 @@ import ( "golang.zx2c4.com/wireguard/tun/wintun/setupapi" ) +// +// Wintun is a handle of a Wintun adapter +// type Wintun windows.GUID -var deviceClassNetGUID = windows.GUID{0x4d36e972, 0xe325, 0x11ce, [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}} +var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}} -const TUN_HWID = "Wintun" +const hardwareID = "Wintun" // // GetInterface finds interface ID by name. @@ -66,7 +69,7 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) { } // Get interface ID. - ifid, err := getInterfaceId(devInfoList, deviceData, 1) + ifid, err := getInterfaceID(devInfoList, deviceData, 1) if err != nil { // Something is wrong with this device. Skip it. continue @@ -106,7 +109,7 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) { continue } - if driverDetailData.IsCompatible(TUN_HWID) { + if driverDetailData.IsCompatible(hardwareID) { // Matching hardware ID found. return (*Wintun)(ifid), nil } @@ -160,7 +163,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err } // Set Plug&Play device hardware ID property. - hwid, err := syscall.UTF16FromString(TUN_HWID) + hwid, err := syscall.UTF16FromString(hardwareID) if err != nil { return nil, false, err } @@ -199,7 +202,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err continue } - if driverDetailData.IsCompatible(TUN_HWID) { + if driverDetailData.IsCompatible(hardwareID) { // Matching hardware ID found. Select the driver. err := devInfoList.SetSelectedDriver(deviceData, driverData) if err != nil { @@ -214,7 +217,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err } if driverVersion == 0 { - return nil, false, fmt.Errorf("No driver for device \"%v\" installed", TUN_HWID) + return nil, false, fmt.Errorf("No driver for device \"%v\" installed", hardwareID) } // Call appropriate class installer. @@ -241,7 +244,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err } // Get network interface ID from registry. Retry for max 30sec. - ifid, err = getInterfaceId(devInfoList, deviceData, 30) + ifid, err = getInterfaceID(devInfoList, deviceData, 30) } if err == nil { @@ -302,7 +305,7 @@ func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, bool, error) { } // Get interface ID. - ifid2, err := getInterfaceId(devInfoList, deviceData, 1) + ifid2, err := getInterfaceID(devInfoList, deviceData, 1) if err != nil { // Something is wrong with this device. Skip it. continue @@ -364,7 +367,7 @@ func checkReboot(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInf return false, nil } -// getInterfaceId returns network interface ID. +// getInterfaceID returns network interface ID. // // After the device is created, it might take some time before the registry // key is populated. numAttempts parameter specifies the number of attempts @@ -373,7 +376,7 @@ func checkReboot(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInf // // Function returns the network interface ID. // -func getInterfaceId(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfoData, numAttempts int) (*windows.GUID, error) { +func getInterfaceID(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfoData, numAttempts int) (*windows.GUID, error) { if numAttempts < 1 { return nil, fmt.Errorf("Invalid numAttempts (expected: >=1, provided: %v)", numAttempts) } @@ -481,10 +484,16 @@ func getRegStringValue(key registry.Key, name string) (string, error) { return valueExp, nil } +// +// SignalEventName returns Wintun device data-ready event name. +// func (wintun *Wintun) SignalEventName() string { return fmt.Sprintf("Global\\WINTUN_EVENT_%s", guid.ToString((*windows.GUID)(wintun))) } +// +// DataFileName returns Wintun device data pipe name. +// func (wintun *Wintun) DataFileName() string { return fmt.Sprintf("\\\\.\\Global\\WINTUN_DEVICE_%s", guid.ToString((*windows.GUID)(wintun))) }