mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
parent
c140ffdbc8
commit
fa49c73238
259
src/platform/networks_windows.go
Normal file
259
src/platform/networks_windows.go
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
package platform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
wlanapi = syscall.NewLazyDLL("wlanapi.dll")
|
||||||
|
hWlanOpenHandle = wlanapi.NewProc("WlanOpenHandle")
|
||||||
|
hWlanCloseHandle = wlanapi.NewProc("WlanCloseHandle")
|
||||||
|
hWlanQueryInterface = wlanapi.NewProc("WlanQueryInterface")
|
||||||
|
hWlanEnumInterfaces = wlanapi.NewProc("WlanEnumInterfaces")
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
type MIN_IF_TABLE2 struct {
|
||||||
|
NumEntries uint64
|
||||||
|
Table [256]MIB_IF_ROW2
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
const (
|
||||||
|
IF_MAX_STRING_SIZE uint64 = 256
|
||||||
|
IF_MAX_PHYS_ADDRESS_LENGTH uint64 = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
type MIB_IF_ROW2 struct {
|
||||||
|
InterfaceLuid uint64
|
||||||
|
InterfaceIndex uint32
|
||||||
|
InterfaceGUID windows.GUID
|
||||||
|
Alias [IF_MAX_STRING_SIZE + 1]uint16
|
||||||
|
Description [IF_MAX_STRING_SIZE + 1]uint16
|
||||||
|
PhysicalAddressLength uint32
|
||||||
|
PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||||
|
PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||||
|
|
||||||
|
Mtu uint32
|
||||||
|
Type uint32
|
||||||
|
TunnelType uint32
|
||||||
|
MediaType uint32
|
||||||
|
PhysicalMediumType uint32
|
||||||
|
AccessType uint32
|
||||||
|
DirectionType uint32
|
||||||
|
|
||||||
|
InterfaceAndOperStatusFlags struct {
|
||||||
|
HardwareInterface bool
|
||||||
|
FilterInterface bool
|
||||||
|
ConnectorPresent bool
|
||||||
|
NotAuthenticated bool
|
||||||
|
NotMediaConnected bool
|
||||||
|
Paused bool
|
||||||
|
LowPower bool
|
||||||
|
EndPointInterface bool
|
||||||
|
}
|
||||||
|
|
||||||
|
OperStatus uint32
|
||||||
|
AdminStatus uint32
|
||||||
|
MediaConnectState uint32
|
||||||
|
NetworkGUID windows.GUID
|
||||||
|
ConnectionType uint32
|
||||||
|
|
||||||
|
TransmitLinkSpeed uint64
|
||||||
|
ReceiveLinkSpeed uint64
|
||||||
|
|
||||||
|
InOctets uint64
|
||||||
|
InUcastPkts uint64
|
||||||
|
InNUcastPkts uint64
|
||||||
|
InDiscards uint64
|
||||||
|
InErrors uint64
|
||||||
|
InUnknownProtos uint64
|
||||||
|
InUcastOctets uint64
|
||||||
|
InMulticastOctets uint64
|
||||||
|
InBroadcastOctets uint64
|
||||||
|
OutOctets uint64
|
||||||
|
OutUcastPkts uint64
|
||||||
|
OutNUcastPkts uint64
|
||||||
|
OutDiscards uint64
|
||||||
|
OutErrors uint64
|
||||||
|
OutUcastOctets uint64
|
||||||
|
OutMulticastOctets uint64
|
||||||
|
OutBroadcastOctets uint64
|
||||||
|
OutQLen uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive, unused
|
||||||
|
type WLAN_INTERFACE_INFO_LIST struct {
|
||||||
|
dwNumberOfItems uint32
|
||||||
|
dwIndex uint32
|
||||||
|
InterfaceInfo [1]WLAN_INTERFACE_INFO
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
type WLAN_INTERFACE_INFO struct {
|
||||||
|
InterfaceGuid syscall.GUID
|
||||||
|
strInterfaceDescription [256]uint16
|
||||||
|
isState uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive, unused
|
||||||
|
type WLAN_CONNECTION_ATTRIBUTES struct {
|
||||||
|
isState uint32
|
||||||
|
wlanConnectionMode uint32
|
||||||
|
strProfileName [256]uint16
|
||||||
|
wlanAssociationAttributes WLAN_ASSOCIATION_ATTRIBUTES
|
||||||
|
wlanSecurityAttributes WLAN_SECURITY_ATTRIBUTES
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive, unused
|
||||||
|
type WLAN_ASSOCIATION_ATTRIBUTES struct {
|
||||||
|
dot11Ssid DOT11_SSID
|
||||||
|
dot11BssType uint32
|
||||||
|
dot11Bssid [6]uint8
|
||||||
|
dot11PhyType uint32
|
||||||
|
uDot11PhyIndex uint32
|
||||||
|
wlanSignalQuality uint32
|
||||||
|
ulRxRate uint32
|
||||||
|
ulTxRate uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive, unused
|
||||||
|
type WLAN_SECURITY_ATTRIBUTES struct {
|
||||||
|
bSecurityEnabled uint32
|
||||||
|
bOneXEnabled uint32
|
||||||
|
dot11AuthAlgorithm uint32
|
||||||
|
dot11CipherAlgorithm uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:revive
|
||||||
|
type DOT11_SSID struct {
|
||||||
|
uSSIDLength uint32
|
||||||
|
ucSSID [32]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (env *Shell) getConnections() []*Connection {
|
||||||
|
var pIFTable2 *MIN_IF_TABLE2
|
||||||
|
_, _, _ = hGetIfTable2.Call(uintptr(unsafe.Pointer(&pIFTable2)))
|
||||||
|
|
||||||
|
networks := make([]*Connection, 0)
|
||||||
|
|
||||||
|
for i := 0; i < int(pIFTable2.NumEntries); i++ {
|
||||||
|
networkInterface := pIFTable2.Table[i]
|
||||||
|
alias := strings.TrimRight(syscall.UTF16ToString(networkInterface.Alias[:]), "\x00")
|
||||||
|
description := strings.TrimRight(syscall.UTF16ToString(networkInterface.Description[:]), "\x00")
|
||||||
|
|
||||||
|
if networkInterface.OperStatus != 1 || // not connected or functional
|
||||||
|
!networkInterface.InterfaceAndOperStatusFlags.HardwareInterface || // rule out software interfaces
|
||||||
|
strings.HasPrefix(alias, "Local Area Connection") || // not relevant
|
||||||
|
strings.Index(alias, "-") >= 3 { // rule out parts of Ethernet filter interfaces
|
||||||
|
// e.g. : "Ethernet-WFP Native MAC Layer LightWeight Filter-0000"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var connectionType ConnectionType
|
||||||
|
var ssid string
|
||||||
|
switch networkInterface.Type {
|
||||||
|
case 6:
|
||||||
|
connectionType = ETHERNET
|
||||||
|
case 237, 234, 244:
|
||||||
|
connectionType = CELLULAR
|
||||||
|
}
|
||||||
|
|
||||||
|
if networkInterface.PhysicalMediumType == 10 {
|
||||||
|
connectionType = BLUETOOTH
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip connections which aren't relevant
|
||||||
|
if len(connectionType) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
network := &Connection{
|
||||||
|
Type: connectionType,
|
||||||
|
Name: description, // we want a relatable name, alias isn't that
|
||||||
|
TransmitRate: networkInterface.TransmitLinkSpeed,
|
||||||
|
ReceiveRate: networkInterface.ReceiveLinkSpeed,
|
||||||
|
SSID: ssid,
|
||||||
|
}
|
||||||
|
|
||||||
|
networks = append(networks, network)
|
||||||
|
}
|
||||||
|
|
||||||
|
if wifi, err := env.wifiNetwork(); err == nil {
|
||||||
|
networks = append(networks, wifi)
|
||||||
|
}
|
||||||
|
|
||||||
|
return networks
|
||||||
|
}
|
||||||
|
|
||||||
|
func (env *Shell) wifiNetwork() (*Connection, error) {
|
||||||
|
env.Trace(time.Now(), "wifiNetwork")
|
||||||
|
// Open handle
|
||||||
|
var pdwNegotiatedVersion uint32
|
||||||
|
var phClientHandle uint32
|
||||||
|
e, _, err := hWlanOpenHandle.Call(uintptr(uint32(2)), uintptr(unsafe.Pointer(nil)), uintptr(unsafe.Pointer(&pdwNegotiatedVersion)), uintptr(unsafe.Pointer(&phClientHandle)))
|
||||||
|
if e != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// defer closing handle
|
||||||
|
defer func() {
|
||||||
|
_, _, _ = hWlanCloseHandle.Call(uintptr(phClientHandle), uintptr(unsafe.Pointer(nil)))
|
||||||
|
}()
|
||||||
|
|
||||||
|
// list interfaces
|
||||||
|
var interfaceList *WLAN_INTERFACE_INFO_LIST
|
||||||
|
e, _, err = hWlanEnumInterfaces.Call(uintptr(phClientHandle), uintptr(unsafe.Pointer(nil)), uintptr(unsafe.Pointer(&interfaceList)))
|
||||||
|
if e != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// use first interface that is connected
|
||||||
|
numberOfInterfaces := int(interfaceList.dwNumberOfItems)
|
||||||
|
infoSize := unsafe.Sizeof(interfaceList.InterfaceInfo[0])
|
||||||
|
for i := 0; i < numberOfInterfaces; i++ {
|
||||||
|
network := (*WLAN_INTERFACE_INFO)(unsafe.Pointer(uintptr(unsafe.Pointer(&interfaceList.InterfaceInfo[0])) + uintptr(i)*infoSize))
|
||||||
|
if network.isState != 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return env.parseNetworkInterface(network, phClientHandle)
|
||||||
|
}
|
||||||
|
return nil, errors.New("Not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (env *Shell) parseNetworkInterface(network *WLAN_INTERFACE_INFO, clientHandle uint32) (*Connection, error) {
|
||||||
|
info := Connection{}
|
||||||
|
|
||||||
|
// Query wifi connection state
|
||||||
|
var dataSize uint16
|
||||||
|
var wlanAttr *WLAN_CONNECTION_ATTRIBUTES
|
||||||
|
e, _, err := hWlanQueryInterface.Call(uintptr(clientHandle),
|
||||||
|
uintptr(unsafe.Pointer(&network.InterfaceGuid)),
|
||||||
|
uintptr(7), // wlan_intf_opcode_current_connection
|
||||||
|
uintptr(unsafe.Pointer(nil)),
|
||||||
|
uintptr(unsafe.Pointer(&dataSize)),
|
||||||
|
uintptr(unsafe.Pointer(&wlanAttr)),
|
||||||
|
uintptr(unsafe.Pointer(nil)))
|
||||||
|
if e != 0 {
|
||||||
|
env.Log(Error, "parseNetworkInterface", "wlan_intf_opcode_current_connection error")
|
||||||
|
return &info, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSID
|
||||||
|
ssid := wlanAttr.wlanAssociationAttributes.dot11Ssid
|
||||||
|
if ssid.uSSIDLength > 0 {
|
||||||
|
info.SSID = string(ssid.ucSSID[0:ssid.uSSIDLength])
|
||||||
|
}
|
||||||
|
|
||||||
|
info.TransmitRate = uint64(wlanAttr.wlanAssociationAttributes.ulTxRate / 1024)
|
||||||
|
info.ReceiveRate = uint64(wlanAttr.wlanAssociationAttributes.ulRxRate / 1024)
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
//go:build windows
|
|
||||||
|
|
||||||
package platform
|
package platform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -196,201 +194,3 @@ func readWinAppLink(path string) (string, error) {
|
||||||
}
|
}
|
||||||
return appExecLink.Path()
|
return appExecLink.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
// networks
|
|
||||||
|
|
||||||
func (env *Shell) getConnections() []*Connection {
|
|
||||||
var pIFTable2 *MIN_IF_TABLE2
|
|
||||||
_, _, _ = hGetIfTable2.Call(uintptr(unsafe.Pointer(&pIFTable2)))
|
|
||||||
|
|
||||||
networks := make([]*Connection, 0)
|
|
||||||
|
|
||||||
for i := 0; i < int(pIFTable2.NumEntries); i++ {
|
|
||||||
networkInterface := pIFTable2.Table[i]
|
|
||||||
alias := strings.TrimRight(syscall.UTF16ToString(networkInterface.Alias[:]), "\x00")
|
|
||||||
description := strings.TrimRight(syscall.UTF16ToString(networkInterface.Description[:]), "\x00")
|
|
||||||
|
|
||||||
if networkInterface.OperStatus != 1 || // not connected or functional
|
|
||||||
!networkInterface.InterfaceAndOperStatusFlags.HardwareInterface || // rule out software interfaces
|
|
||||||
strings.HasPrefix(alias, "Local Area Connection") || // not relevant
|
|
||||||
strings.Index(alias, "-") >= 3 { // rule out parts of Ethernet filter interfaces
|
|
||||||
// e.g. : "Ethernet-WFP Native MAC Layer LightWeight Filter-0000"
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var connectionType ConnectionType
|
|
||||||
var ssid string
|
|
||||||
switch networkInterface.Type {
|
|
||||||
case 6:
|
|
||||||
connectionType = ETHERNET
|
|
||||||
case 71:
|
|
||||||
connectionType = WIFI
|
|
||||||
ssid = env.getWiFiSSID(networkInterface.InterfaceGUID)
|
|
||||||
case 237, 234, 244:
|
|
||||||
connectionType = CELLULAR
|
|
||||||
}
|
|
||||||
|
|
||||||
if networkInterface.PhysicalMediumType == 10 {
|
|
||||||
connectionType = BLUETOOTH
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip connections which aren't relevant
|
|
||||||
if len(connectionType) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
network := &Connection{
|
|
||||||
Type: connectionType,
|
|
||||||
Name: description, // we want a relatable name, alias isn't that
|
|
||||||
TransmitRate: networkInterface.TransmitLinkSpeed,
|
|
||||||
ReceiveRate: networkInterface.ReceiveLinkSpeed,
|
|
||||||
SSID: ssid,
|
|
||||||
}
|
|
||||||
|
|
||||||
networks = append(networks, network)
|
|
||||||
}
|
|
||||||
return networks
|
|
||||||
}
|
|
||||||
|
|
||||||
type MIN_IF_TABLE2 struct { //nolint: revive
|
|
||||||
NumEntries uint64
|
|
||||||
Table [256]MIB_IF_ROW2
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
IF_MAX_STRING_SIZE uint64 = 256 //nolint: revive
|
|
||||||
IF_MAX_PHYS_ADDRESS_LENGTH uint64 = 32 //nolint: revive
|
|
||||||
)
|
|
||||||
|
|
||||||
type MIB_IF_ROW2 struct { //nolint: revive
|
|
||||||
InterfaceLuid uint64
|
|
||||||
InterfaceIndex uint32
|
|
||||||
InterfaceGUID windows.GUID
|
|
||||||
Alias [IF_MAX_STRING_SIZE + 1]uint16
|
|
||||||
Description [IF_MAX_STRING_SIZE + 1]uint16
|
|
||||||
PhysicalAddressLength uint32
|
|
||||||
PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
|
||||||
PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
|
||||||
|
|
||||||
Mtu uint32
|
|
||||||
Type uint32
|
|
||||||
TunnelType uint32
|
|
||||||
MediaType uint32
|
|
||||||
PhysicalMediumType uint32
|
|
||||||
AccessType uint32
|
|
||||||
DirectionType uint32
|
|
||||||
|
|
||||||
InterfaceAndOperStatusFlags struct {
|
|
||||||
HardwareInterface bool
|
|
||||||
FilterInterface bool
|
|
||||||
ConnectorPresent bool
|
|
||||||
NotAuthenticated bool
|
|
||||||
NotMediaConnected bool
|
|
||||||
Paused bool
|
|
||||||
LowPower bool
|
|
||||||
EndPointInterface bool
|
|
||||||
}
|
|
||||||
|
|
||||||
OperStatus uint32
|
|
||||||
AdminStatus uint32
|
|
||||||
MediaConnectState uint32
|
|
||||||
NetworkGUID windows.GUID
|
|
||||||
ConnectionType uint32
|
|
||||||
|
|
||||||
TransmitLinkSpeed uint64
|
|
||||||
ReceiveLinkSpeed uint64
|
|
||||||
|
|
||||||
InOctets uint64
|
|
||||||
InUcastPkts uint64
|
|
||||||
InNUcastPkts uint64
|
|
||||||
InDiscards uint64
|
|
||||||
InErrors uint64
|
|
||||||
InUnknownProtos uint64
|
|
||||||
InUcastOctets uint64
|
|
||||||
InMulticastOctets uint64
|
|
||||||
InBroadcastOctets uint64
|
|
||||||
OutOctets uint64
|
|
||||||
OutUcastPkts uint64
|
|
||||||
OutNUcastPkts uint64
|
|
||||||
OutDiscards uint64
|
|
||||||
OutErrors uint64
|
|
||||||
OutUcastOctets uint64
|
|
||||||
OutMulticastOctets uint64
|
|
||||||
OutBroadcastOctets uint64
|
|
||||||
OutQLen uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
wlanapi = syscall.NewLazyDLL("wlanapi.dll")
|
|
||||||
hWlanOpenHandle = wlanapi.NewProc("WlanOpenHandle")
|
|
||||||
hWlanCloseHandle = wlanapi.NewProc("WlanCloseHandle")
|
|
||||||
hWlanQueryInterface = wlanapi.NewProc("WlanQueryInterface")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (env *Shell) getWiFiSSID(guid windows.GUID) string {
|
|
||||||
// Query wifi connection state
|
|
||||||
var pdwNegotiatedVersion uint32
|
|
||||||
var phClientHandle uint32
|
|
||||||
e, _, err := hWlanOpenHandle.Call(uintptr(uint32(2)), uintptr(unsafe.Pointer(nil)), uintptr(unsafe.Pointer(&pdwNegotiatedVersion)), uintptr(unsafe.Pointer(&phClientHandle)))
|
|
||||||
if e != 0 {
|
|
||||||
env.Log(Error, "getAllWifiSSID", err.Error())
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// defer closing handle
|
|
||||||
defer func() {
|
|
||||||
_, _, _ = hWlanCloseHandle.Call(uintptr(phClientHandle), uintptr(unsafe.Pointer(nil)))
|
|
||||||
}()
|
|
||||||
|
|
||||||
var dataSize uint16
|
|
||||||
var wlanAttr *WLAN_CONNECTION_ATTRIBUTES
|
|
||||||
|
|
||||||
e, _, _ = hWlanQueryInterface.Call(uintptr(phClientHandle),
|
|
||||||
uintptr(unsafe.Pointer(&guid)),
|
|
||||||
uintptr(7), // wlan_intf_opcode_current_connection
|
|
||||||
uintptr(unsafe.Pointer(nil)),
|
|
||||||
uintptr(unsafe.Pointer(&dataSize)),
|
|
||||||
uintptr(unsafe.Pointer(&wlanAttr)),
|
|
||||||
uintptr(unsafe.Pointer(nil)))
|
|
||||||
if e != 0 {
|
|
||||||
env.Log(Error, "parseWlanInterface", "wlan_intf_opcode_current_connection error")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
ssid := wlanAttr.wlanAssociationAttributes.dot11Ssid
|
|
||||||
if ssid.uSSIDLength <= 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(ssid.ucSSID[0:ssid.uSSIDLength])
|
|
||||||
}
|
|
||||||
|
|
||||||
type WLAN_CONNECTION_ATTRIBUTES struct { //nolint: revive
|
|
||||||
isState uint32 //nolint: unused
|
|
||||||
wlanConnectionMode uint32 //nolint: unused
|
|
||||||
strProfileName [256]uint16 //nolint: unused
|
|
||||||
wlanAssociationAttributes WLAN_ASSOCIATION_ATTRIBUTES
|
|
||||||
wlanSecurityAttributes WLAN_SECURITY_ATTRIBUTES //nolint: unused
|
|
||||||
}
|
|
||||||
|
|
||||||
type WLAN_ASSOCIATION_ATTRIBUTES struct { //nolint: revive
|
|
||||||
dot11Ssid DOT11_SSID
|
|
||||||
dot11BssType uint32 //nolint: unused
|
|
||||||
dot11Bssid [6]uint8 //nolint: unused
|
|
||||||
dot11PhyType uint32 //nolint: unused
|
|
||||||
uDot11PhyIndex uint32 //nolint: unused
|
|
||||||
wlanSignalQuality uint32 //nolint: unused
|
|
||||||
ulRxRate uint32 //nolint: unused
|
|
||||||
ulTxRate uint32 //nolint: unused
|
|
||||||
}
|
|
||||||
|
|
||||||
type WLAN_SECURITY_ATTRIBUTES struct { //nolint: revive
|
|
||||||
bSecurityEnabled uint32 //nolint: unused
|
|
||||||
bOneXEnabled uint32 //nolint: unused
|
|
||||||
dot11AuthAlgorithm uint32 //nolint: unused
|
|
||||||
dot11CipherAlgorithm uint32 //nolint: unused
|
|
||||||
}
|
|
||||||
|
|
||||||
type DOT11_SSID struct { //nolint: revive
|
|
||||||
uSSIDLength uint32
|
|
||||||
ucSSID [32]uint8
|
|
||||||
}
|
|
Loading…
Reference in a new issue