github.com/zooyer/miskit@v1.0.71/device/interface_windows.go (about) 1 /** 2 * @Author: zzy 3 * @Email: zhangzhongyuan@didiglobal.com 4 * @Description: 5 * @File: interface_windows.go 6 * @Package: device 7 * @Version: 1.0.0 8 * @Date: 2022/10/5 14:43 9 */ 10 11 package device 12 13 import ( 14 "fmt" 15 "strings" 16 _ "unsafe" 17 18 "golang.org/x/sys/windows" 19 "golang.org/x/sys/windows/registry" 20 ) 21 22 //go:linkname adapterAddresses net.adapterAddresses 23 func adapterAddresses() ([]*windows.IpAdapterAddresses, error) 24 25 func regString(key registry.Key, path, name string) (value string, err error) { 26 subKey, err := registry.OpenKey(key, path, registry.READ) 27 if err != nil { 28 return 29 } 30 31 defer subKey.Close() 32 33 if value, _, err = subKey.GetStringValue(name); err != nil { 34 return 35 } 36 37 return 38 } 39 40 func regInteger(key registry.Key, path, name string) (value uint64, err error) { 41 subKey, err := registry.OpenKey(key, path, registry.READ) 42 if err != nil { 43 return 44 } 45 46 defer subKey.Close() 47 48 if value, _, err = subKey.GetIntegerValue(name); err != nil { 49 return 50 } 51 52 return 53 } 54 55 // isPhysical1 判断设备前缀 56 func isPhysical1(name string) (is bool, err error) { 57 var path = fmt.Sprintf("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", name) 58 59 instance, err := regString(registry.LOCAL_MACHINE, path, "PnPInstanceId") 60 if err != nil { 61 return 62 } 63 64 // 不包含USB网卡 65 return strings.HasPrefix(instance, "PCI"), nil 66 } 67 68 // isPhysical2 判断设备前缀和属性 69 func isPhysical2(name string) (is bool, err error) { 70 const path = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}" 71 key, err := registry.OpenKey(registry.LOCAL_MACHINE, path, registry.READ) 72 if err != nil { 73 return 74 } 75 76 defer key.Close() 77 78 stat, err := key.Stat() 79 if err != nil { 80 return 81 } 82 83 subs, err := key.ReadSubKeyNames(int(stat.SubKeyCount)) 84 if err != nil { 85 return 86 } 87 88 for _, sub := range subs { 89 instance, err := regString(key, sub, "NetCfgInstanceId") 90 if err == registry.ErrNotExist || err != nil || instance != name { 91 continue 92 } 93 94 // 不包含USB网卡 95 device, err := regString(key, sub, "DeviceInstanceID") 96 if err == registry.ErrNotExist || err != nil || !strings.HasPrefix(device, "PCI") { 97 continue 98 } 99 100 // ox4 NCF_PHYSICAL 说明组件是一个物理适配器 101 value, err := regInteger(key, sub, "Characteristics") 102 if err == nil && value&0x4 == 0x4 { 103 return true, nil 104 } 105 } 106 107 return 108 } 109 110 // isPhysical3 isPhysical1增强版本,通过bus方式判断:https://blog.csdn.net/whf727/article/details/6660815 111 func isPhysical3(name string) (is bool, err error) { 112 var path = fmt.Sprintf("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", name) 113 114 instance, err := regString(registry.LOCAL_MACHINE, path, "PnPInstanceId") 115 if err != nil { 116 return 117 } 118 119 // 不包含USB网卡 120 if !strings.HasPrefix(instance, "PCI") { 121 return 122 } 123 124 guid, err := windows.GUIDFromString("{4D36E972-E325-11CE-BFC1-08002BE10318}") 125 if err != nil { 126 return 127 } 128 129 dev, err := windows.SetupDiGetClassDevsEx(&guid, "", 0, windows.DIGCF_PRESENT, 0, "") 130 if err != nil { 131 return 132 } 133 134 defer dev.Close() 135 136 for i := 0; ; i++ { 137 info, err := dev.EnumDeviceInfo(i) 138 if err != nil { 139 if err == windows.ERROR_NO_MORE_ITEMS { 140 break 141 } 142 continue 143 } 144 145 id, err := dev.DeviceInstanceID(info) 146 if err != nil { 147 continue 148 } 149 150 if !strings.EqualFold(id, instance) { 151 continue 152 } 153 154 value, err := dev.DeviceRegistryProperty(info, windows.SPDRP_BUSNUMBER) 155 if err != nil { 156 continue 157 } 158 159 if num, ok := value.(uint32); ok && int32(num) != -1 { 160 return true, nil 161 } 162 } 163 164 return false, nil 165 } 166 167 func isPhysicalEthernet(index int) (is bool, err error) { 168 aas, err := adapterAddresses() 169 if err != nil { 170 return 171 } 172 173 for _, aa := range aas { 174 if int(aa.IfIndex) != index { 175 continue 176 } 177 178 // 有线网卡和无线网卡 179 if aa.IfType == windows.IF_TYPE_ETHERNET_CSMACD || aa.IfType == windows.IF_TYPE_IEEE80211 { 180 return isPhysical3(windows.BytePtrToString(aa.AdapterName)) 181 } 182 } 183 184 return 185 }