wintun: get interface path properly with cfgmgr
This commit is contained in:
parent
eeeac287ef
commit
a2249449d6
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -38,6 +38,7 @@ func errnoErr(e syscall.Errno) error {
|
||||
|
||||
var (
|
||||
modsetupapi = windows.NewLazySystemDLL("setupapi.dll")
|
||||
modCfgMgr32 = windows.NewLazySystemDLL("CfgMgr32.dll")
|
||||
|
||||
procSetupDiCreateDeviceInfoListExW = modsetupapi.NewProc("SetupDiCreateDeviceInfoListExW")
|
||||
procSetupDiGetDeviceInfoListDetailW = modsetupapi.NewProc("SetupDiGetDeviceInfoListDetailW")
|
||||
@ -65,6 +66,8 @@ var (
|
||||
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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user