summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tun/wintun/setupapi/setupapi_windows.go35
-rw-r--r--tun/wintun/setupapi/types_windows.go10
-rw-r--r--tun/wintun/setupapi/zsetupapi_windows.go69
-rw-r--r--tun/wintun/wintun_windows.go9
4 files changed, 93 insertions, 30 deletions
diff --git a/tun/wintun/setupapi/setupapi_windows.go b/tun/wintun/setupapi/setupapi_windows.go
index 764b3e6..60a8eb7 100644
--- a/tun/wintun/setupapi/setupapi_windows.go
+++ b/tun/wintun/setupapi/setupapi_windows.go
@@ -469,3 +469,38 @@ func (deviceInfoSet DevInfo) SelectedDevice() (*DevInfoData, error) {
func (deviceInfoSet DevInfo) SetSelectedDevice(deviceInfoData *DevInfoData) error {
return SetupDiSetSelectedDevice(deviceInfoSet, deviceInfoData)
}
+
+//sys cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *windows.GUID, deviceID *uint16, flags uint32) (ret uint32) = CfgMgr32.CM_Get_Device_Interface_List_SizeW
+//sys cm_Get_Device_Interface_List(interfaceClass *windows.GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret uint32) = CfgMgr32.CM_Get_Device_Interface_ListW
+
+func CM_Get_Device_Interface_List(deviceID string, interfaceClass *windows.GUID, flags uint32) ([]string, error) {
+ deviceID16, err := windows.UTF16PtrFromString(deviceID)
+ if err != nil {
+ return nil, err
+ }
+ var buf []uint16
+ var buflen uint32
+ for {
+ if ret := cm_Get_Device_Interface_List_Size(&buflen, interfaceClass, deviceID16, flags); ret != CR_SUCCESS {
+ return nil, fmt.Errorf("CfgMgr error: 0x%x", ret)
+ }
+ buf = make([]uint16, buflen)
+ if ret := cm_Get_Device_Interface_List(interfaceClass, deviceID16, &buf[0], buflen, flags); ret == CR_SUCCESS {
+ break
+ } else if ret != CR_BUFFER_SMALL {
+ return nil, fmt.Errorf("CfgMgr error: 0x%x", ret)
+ }
+ }
+ var interfaces []string
+ for i := 0; i < len(buf); {
+ j := i + wcslen(buf[i:])
+ if i < j {
+ interfaces = append(interfaces, windows.UTF16ToString(buf[i:j]))
+ }
+ i = j + 1
+ }
+ if interfaces == nil {
+ return nil, fmt.Errorf("no interfaces found")
+ }
+ return interfaces, nil
+}
diff --git a/tun/wintun/setupapi/types_windows.go b/tun/wintun/setupapi/types_windows.go
index 6ceda09..136b4be 100644
--- a/tun/wintun/setupapi/types_windows.go
+++ b/tun/wintun/setupapi/types_windows.go
@@ -556,3 +556,13 @@ const (
SPDRP_MAXIMUM_PROPERTY SPDRP = 0x00000025 // Upper bound on ordinals
)
+
+const (
+ CR_SUCCESS = 0x0
+ CR_BUFFER_SMALL = 0x1a
+)
+
+const (
+ CM_GET_DEVICE_INTERFACE_LIST_PRESENT = 0 // only currently 'live' device interfaces
+ CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES = 1 // all registered device interfaces, live or not
+)
diff --git a/tun/wintun/setupapi/zsetupapi_windows.go b/tun/wintun/setupapi/zsetupapi_windows.go
index 0949718..375862d 100644
--- a/tun/wintun/setupapi/zsetupapi_windows.go
+++ b/tun/wintun/setupapi/zsetupapi_windows.go
@@ -38,33 +38,36 @@ func errnoErr(e syscall.Errno) error {
var (
modsetupapi = windows.NewLazySystemDLL("setupapi.dll")
-
- procSetupDiCreateDeviceInfoListExW = modsetupapi.NewProc("SetupDiCreateDeviceInfoListExW")
- procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW")
- procSetupDiCreateDeviceInfoW = modsetupapi.NewProc("SetupDiCreateDeviceInfoW")
- procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo")
- procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList")
- procSetupDiBuildDriverInfoList = modsetupapi.NewProc("SetupDiBuildDriverInfoList")
- procSetupDiCancelDriverInfoSearch = modsetupapi.NewProc("SetupDiCancelDriverInfoSearch")
- procSetupDiEnumDriverInfoW = modsetupapi.NewProc("SetupDiEnumDriverInfoW")
- procSetupDiGetSelectedDriverW = modsetupapi.NewProc("SetupDiGetSelectedDriverW")
- procSetupDiSetSelectedDriverW = modsetupapi.NewProc("SetupDiSetSelectedDriverW")
- procSetupDiGetDriverInfoDetailW = modsetupapi.NewProc("SetupDiGetDriverInfoDetailW")
- procSetupDiDestroyDriverInfoList = modsetupapi.NewProc("SetupDiDestroyDriverInfoList")
- procSetupDiGetClassDevsExW = modsetupapi.NewProc("SetupDiGetClassDevsExW")
- procSetupDiCallClassInstaller = modsetupapi.NewProc("SetupDiCallClassInstaller")
- procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey")
- procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW")
- procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW")
- procSetupDiGetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW")
- procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW")
- procSetupDiGetClassInstallParamsW = modsetupapi.NewProc("SetupDiGetClassInstallParamsW")
- procSetupDiSetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiSetDeviceInstallParamsW")
- procSetupDiSetClassInstallParamsW = modsetupapi.NewProc("SetupDiSetClassInstallParamsW")
- procSetupDiClassNameFromGuidExW = modsetupapi.NewProc("SetupDiClassNameFromGuidExW")
- procSetupDiClassGuidsFromNameExW = modsetupapi.NewProc("SetupDiClassGuidsFromNameExW")
- procSetupDiGetSelectedDevice = modsetupapi.NewProc("SetupDiGetSelectedDevice")
- procSetupDiSetSelectedDevice = modsetupapi.NewProc("SetupDiSetSelectedDevice")
+ modCfgMgr32 = windows.NewLazySystemDLL("CfgMgr32.dll")
+
+ procSetupDiCreateDeviceInfoListExW = modsetupapi.NewProc("SetupDiCreateDeviceInfoListExW")
+ procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW")
+ procSetupDiCreateDeviceInfoW = modsetupapi.NewProc("SetupDiCreateDeviceInfoW")
+ procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo")
+ procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList")
+ procSetupDiBuildDriverInfoList = modsetupapi.NewProc("SetupDiBuildDriverInfoList")
+ procSetupDiCancelDriverInfoSearch = modsetupapi.NewProc("SetupDiCancelDriverInfoSearch")
+ procSetupDiEnumDriverInfoW = modsetupapi.NewProc("SetupDiEnumDriverInfoW")
+ procSetupDiGetSelectedDriverW = modsetupapi.NewProc("SetupDiGetSelectedDriverW")
+ procSetupDiSetSelectedDriverW = modsetupapi.NewProc("SetupDiSetSelectedDriverW")
+ procSetupDiGetDriverInfoDetailW = modsetupapi.NewProc("SetupDiGetDriverInfoDetailW")
+ procSetupDiDestroyDriverInfoList = modsetupapi.NewProc("SetupDiDestroyDriverInfoList")
+ procSetupDiGetClassDevsExW = modsetupapi.NewProc("SetupDiGetClassDevsExW")
+ procSetupDiCallClassInstaller = modsetupapi.NewProc("SetupDiCallClassInstaller")
+ procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey")
+ procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW")
+ procSetupDiSetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiSetDeviceRegistryPropertyW")
+ procSetupDiGetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiGetDeviceInstallParamsW")
+ procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW")
+ procSetupDiGetClassInstallParamsW = modsetupapi.NewProc("SetupDiGetClassInstallParamsW")
+ procSetupDiSetDeviceInstallParamsW = modsetupapi.NewProc("SetupDiSetDeviceInstallParamsW")
+ procSetupDiSetClassInstallParamsW = modsetupapi.NewProc("SetupDiSetClassInstallParamsW")
+ procSetupDiClassNameFromGuidExW = modsetupapi.NewProc("SetupDiClassNameFromGuidExW")
+ procSetupDiClassGuidsFromNameExW = modsetupapi.NewProc("SetupDiClassGuidsFromNameExW")
+ procSetupDiGetSelectedDevice = modsetupapi.NewProc("SetupDiGetSelectedDevice")
+ procSetupDiSetSelectedDevice = modsetupapi.NewProc("SetupDiSetSelectedDevice")
+ procCM_Get_Device_Interface_List_SizeW = modCfgMgr32.NewProc("CM_Get_Device_Interface_List_SizeW")
+ procCM_Get_Device_Interface_ListW = modCfgMgr32.NewProc("CM_Get_Device_Interface_ListW")
)
func setupDiCreateDeviceInfoListEx(classGUID *windows.GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) {
@@ -381,3 +384,15 @@ func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData
}
return
}
+
+func cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *windows.GUID, deviceID *uint16, flags uint32) (ret uint32) {
+ r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_List_SizeW.Addr(), 4, uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags), 0, 0)
+ ret = uint32(r0)
+ return
+}
+
+func cm_Get_Device_Interface_List(interfaceClass *windows.GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret uint32) {
+ r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_ListW.Addr(), 5, uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags), 0)
+ ret = uint32(r0)
+ return
+}
diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go
index 0dabcbb..26ebf60 100644
--- a/tun/wintun/wintun_windows.go
+++ b/tun/wintun/wintun_windows.go
@@ -29,7 +29,7 @@ type Wintun struct {
}
var deviceClassNetGUID = windows.GUID{Data1: 0x4d36e972, Data2: 0xe325, Data3: 0x11ce, Data4: [8]byte{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}
-var deviceInterfaceNetGUID = windows.GUID{Data1: 0xcac88484, Data2: 0x7515, Data3: 0x4c03, Data4: [8]byte{ 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61}}
+var deviceInterfaceNetGUID = windows.GUID{Data1: 0xcac88484, Data2: 0x7515, Data3: 0x4c03, Data4: [8]byte{0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61}}
const (
hardwareID = "Wintun"
@@ -622,8 +622,11 @@ func (wintun *Wintun) deviceData() (setupapi.DevInfo, *setupapi.DevInfoData, err
// AdapterHandle returns a handle to the adapter device object.
func (wintun *Wintun) AdapterHandle() (windows.Handle, error) {
- mangledPnpNode := strings.ReplaceAll(fmt.Sprintf("%s\\%s", wintun.devInstanceID, deviceInterfaceNetGUID.String()), "\\", "#")
- handle, err := windows.CreateFile(windows.StringToUTF16Ptr(fmt.Sprintf("\\\\.\\Global\\%s", mangledPnpNode)), windows.GENERIC_READ|windows.GENERIC_WRITE, windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE, nil, windows.OPEN_EXISTING, 0, 0)
+ interfaces, err := setupapi.CM_Get_Device_Interface_List(wintun.devInstanceID, &deviceInterfaceNetGUID, setupapi.CM_GET_DEVICE_INTERFACE_LIST_PRESENT)
+ if err != nil {
+ return windows.InvalidHandle, err
+ }
+ handle, err := windows.CreateFile(windows.StringToUTF16Ptr(interfaces[0]), windows.GENERIC_READ|windows.GENERIC_WRITE, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE, nil, windows.OPEN_EXISTING, 0, 0)
if err != nil {
return windows.InvalidHandle, fmt.Errorf("Open NDIS device failed: %v", err)
}