]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
wintun: get interface path properly with cfgmgr
authorJason A. Donenfeld <Jason@zx2c4.com>
Tue, 23 Jul 2019 12:58:46 +0000 (14:58 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Tue, 23 Jul 2019 12:58:46 +0000 (14:58 +0200)
tun/wintun/setupapi/setupapi_windows.go
tun/wintun/setupapi/types_windows.go
tun/wintun/setupapi/zsetupapi_windows.go
tun/wintun/wintun_windows.go

index 764b3e6bd8a25c87b3e4b0c2b55c456002bc319c..60a8eb73428529e9fefe304cd62aeba9012c168c 100644 (file)
@@ -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
+}
index 6ceda0910f79077e10cca428f9cb8274780f948e..136b4be976606e7ff4ce9922f71d9ee78051e507 100644 (file)
@@ -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
+)
index 09497183d556a813fcaa5fd7194c69e5fcf81e9f..375862da4b66d8046039393b441dbc1bf58ccb49 100644 (file)
@@ -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
+}
index 0dabcbb70eee6a5d736e9509a152b6b04e145fcb..26ebf6012ff17436528769a7170ebc1e70670e00 100644 (file)
@@ -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)
        }