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