Skip to content

Commit

Permalink
'resourceMonitor_releace_23.05.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
kefaslungu committed May 13, 2023
1 parent 90c8738 commit 6470dbd
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
*.nvda-addon
.sconsign.dblite
*.ini
*.json
suggestions.txt
10 changes: 9 additions & 1 deletion addon/doc/en/readme.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../style.css" media="screen">
<title>Resource Monitor 23.05</title>
<title>Resource Monitor 23.05.1</title>
</head>
<body>
<h1>Resource Monitor</h1>
Expand Down Expand Up @@ -36,6 +36,14 @@ <h2>Usage notes</h2>
</ul>
<p>Note on license: this add-on uses Psutil, licensed under 3-Clause BSD License which is compatible with GNU General Public License.</p>
<h1>Version history:</h1>
<h2>Version 23.05.1</h2>
<p>wlanReporter NVDA-addon is now part of resourceMonitor!</p>
<ul>
<li>The old way of checking for wireless connections has been replaced by the windows API from wlanReporter: https://github.com/kvark128/WlanReporter/ .</li>
<li>After speaking SSID name and strength, NVDA will also now tell you the security type of your network.</li>
<li>NVDA will now alert you when you connect and disconnect from a wireless network.</li>
<li>NVDA will now alert you when wireless connections is turned on or off.</li>
</ul>
<h2>Version 23.05</h2>
<ul>
<li>added the ability to deteched and presents the state of the connected wireless network.</li>
Expand Down
7 changes: 7 additions & 0 deletions addon/doc/en/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ This add-on does not replace task manager and other system information programs
Note on license: this add-on uses Psutil, licensed under 3-Clause BSD License which is compatible with GNU General Public License.

# Version history:
## Version 23.05.1
wlanReporter NVDA-addon is now part of resourceMonitor!

* The old way of checking for wireless connections has been replaced by the windows API from wlanReporter: https://github.com/kvark128/WlanReporter/ .
* After speaking SSID name and strength, NVDA will also now tell you the security type of your network.
* NVDA will now alert you when you connect and disconnect from a wireless network.
* NVDA will now alert you when wireless connections is turned on or off.

## Version 23.05

Expand Down
102 changes: 71 additions & 31 deletions addon/globalPlugins/resourceMonitor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,60 @@
# released under GPL.
# This add-on uses Psutil, licensed under 3-Clause BSD License which is compatible with GPL.

import winreg
import re
import functools
import os.path
import platform
import queueHandler
import winreg
import winsound
from ctypes import addressof, byref, POINTER, wintypes
from datetime import datetime
from subprocess import getoutput
from typing import List, Tuple, Union, Any
import globalPluginHandler
import ui
import api
import globalCommands
import globalPluginHandler
import scriptHandler
import ui
import winVersion
from . import psutil
from . import wlanapi
import addonHandler
addonHandler.initTranslation()
MODULE_DIR = os.path.dirname(__file__)
def message(text, fileName):
ui.message(text)
path = os.path.join(MODULE_DIR, fileName)
if os.path.exists(path):
winsound.PlaySound(path, winsound.SND_ASYNC)

SECURITY_TYPE = {
wlanapi.DOT11_AUTH_ALGO_80211_OPEN: _("No authentication (Open)"),
wlanapi.DOT11_AUTH_ALGO_80211_SHARED_KEY: "WEP",
wlanapi.DOT11_AUTH_ALGO_WPA: "WPA-Enterprise",
wlanapi.DOT11_AUTH_ALGO_WPA_PSK: "WPA-PSK",
wlanapi.DOT11_AUTH_ALGO_RSNA: "WPA2-Enterprise",
wlanapi.DOT11_AUTH_ALGO_RSNA_PSK: "WPA2-PSK",
}
@wlanapi.WLAN_NOTIFICATION_CALLBACK
def notifyHandler(pData, pCtx):
if pData.contents.NotificationSource != wlanapi.WLAN_NOTIFICATION_SOURCE_ACM:
return
if pData.contents.NotificationCode == wlanapi.wlan_notification_acm_connection_complete:
ssid = wlanapi.WLAN_CONNECTION_NOTIFICATION_DATA.from_address(pData.contents.pData).dot11Ssid.SSID
queueHandler.queueFunction(queueHandler.eventQueue, message, _("Connected to {}").format(ssid.decode("utf-8")), "connect.wav")
elif pData.contents.NotificationCode == wlanapi.wlan_notification_acm_disconnected:
ssid = wlanapi.WLAN_CONNECTION_NOTIFICATION_DATA.from_address(pData.contents.pData).dot11Ssid.SSID
queueHandler.queueFunction(queueHandler.eventQueue, message, _("Disconnected from {}").format(ssid.decode("utf-8")), "disconnect.wav")
elif pData.contents.NotificationCode == wlanapi.wlan_notification_acm_interface_arrival:
queueHandler.queueFunction(queueHandler.eventQueue, message, _("A wireless device has been enabled"), "enable.wav")
elif pData.contents.NotificationCode == wlanapi.wlan_notification_acm_interface_removal:
queueHandler.queueFunction(queueHandler.eventQueue, message, _("A wireless device has been disabled"), "disable.wav")

def customResize(array, newSize):
return (array._type_ * newSize).from_address(addressof(array))

# Styles of size calculation/string composition, do not change!
# Treditional style, Y, K, M, G, B, ...
# Traditional style, Y, K, M, G, B, ...
traditional = [
(1024.0**8.0, 'Y'),
(1024.0**7.0, 'Z'),
Expand Down Expand Up @@ -232,10 +268,16 @@ def getWinVer() -> str:


class GlobalPlugin(globalPluginHandler.GlobalPlugin):

# Translators: The gestures category for this add-on in input gestures dialog (2013.3 or later).
scriptCategory = _("Resource Monitor")

def __init__(self):
super().__init__()
self._negotiated_version = wintypes.DWORD()
self._client_handle = wintypes.HANDLE()
wlanapi.WlanOpenHandle(wlanapi.CLIENT_VERSION_WINDOWS_VISTA_OR_LATER, None, byref(self._negotiated_version), byref(self._client_handle))
wlanapi.WlanRegisterNotification(self._client_handle, wlanapi.WLAN_NOTIFICATION_SOURCE_ACM, True, notifyHandler, None, None, None)

@scriptHandler.script(
description=_(
# Translators: Input help message about battery info command in Resource Monitor.
Expand Down Expand Up @@ -359,35 +401,33 @@ def script_announceWinVer(self, gesture):
# Translators: Input help mode message about obtaining the ssid of the wireless network, and the strength of the network.
description=_("Announces the system's wireless network ssid name, and its strength."),
gesture="kb:NVDA+shift+8"
)
def script_network_information(self, gesture):
# Get the SSID of the current network
network_info = getoutput("netsh wlan show interface")
ssid_pattern = re.compile(r'SSID\s+:\s(.+)')
match = ssid_pattern.search(network_info)
if match:
ssid = match.group(1)
else:
# Translators: a message telling the user SSID not found.
ui.message("SSID not found")
return

# Get the signal strength of the current network
signal_strength = re.compile(r'Signal\s+:\s(\d+)')
match = signal_strength.search(network_info)
)
def script_wlanStatusReport(self, gesture):
wlan_ifaces = POINTER(wlanapi.WLAN_INTERFACE_INFO_LIST)()
wlanapi.WlanEnumInterfaces(self._client_handle, None, byref(wlan_ifaces))

if match:
strength = int(match.group(1))
else:
# Translators: Message reported when there is no information on the strength of the ssid
ui.message("Signal strength not found")
if wlan_ifaces.contents.NumberOfItems == 0:
info = _("No wireless devices")
wlanapi.WlanFreeMemory(wlan_ifaces)
return

for i in customResize(wlan_ifaces.contents.InterfaceInfo, wlan_ifaces.contents.NumberOfItems):
if i.isState != wlanapi.wlan_interface_state_connected:
info = _("No wireless connections")
continue

wlan_available_network_list = POINTER(wlanapi.WLAN_AVAILABLE_NETWORK_LIST)()
wlanapi.WlanGetAvailableNetworkList(self._client_handle, byref(i.InterfaceGuid), 0, None, byref(wlan_available_network_list))
for n in customResize(wlan_available_network_list.contents.Network, wlan_available_network_list.contents.NumberOfItems):
if n.Flags & wlanapi.WLAN_AVAILABLE_NETWORK_CONNECTED:
info = _("Connected wireless network: {}. Signal strength: {}%. Security type: {}").format(n.dot11Ssid.SSID.decode(), n.wlanSignalQuality, SECURITY_TYPE.get(n.dot11DefaultAuthAlgorithm))
break
wlanapi.WlanFreeMemory(wlan_available_network_list)
wlanapi.WlanFreeMemory(wlan_ifaces)
if scriptHandler.getLastScriptRepeatCount() == 0:
# Translators: get information on the connected network information, and its strength.
ui.message((f"Connected wireless network: {ssid}, Signal Strength: {strength}%"))
ui.message(info)
else:
api.copyToClip((f"Connected wireless network: {ssid}, Signal Strength: {strength}%"), notify=True)
api.copyToClip(info, notify=True)

def getUptime(self) -> str:
bootTimestamp = psutil.boot_time()
Expand Down
Binary file added addon/globalPlugins/resourceMonitor/connect.wav
Binary file not shown.
Binary file added addon/globalPlugins/resourceMonitor/disable.wav
Binary file not shown.
Binary file not shown.
Binary file added addon/globalPlugins/resourceMonitor/enable.wav
Binary file not shown.
149 changes: 149 additions & 0 deletions addon/globalPlugins/resourceMonitor/wlanapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
from comtypes import GUID
from ctypes import *
from ctypes.wintypes import DWORD, PDWORD, HANDLE, BOOL

wlanapi = windll.wlanapi

WLAN_NOTIFICATION_SOURCE_ALL = 0x0000ffff
WLAN_NOTIFICATION_SOURCE_ACM = 0x00000008
wlan_notification_acm_connection_complete = 0x0000000a
wlan_notification_acm_disconnected = 0x00000015
wlan_notification_acm_interface_arrival = 0x0000000d
wlan_notification_acm_interface_removal = 0x0000000e

WLAN_AVAILABLE_NETWORK_CONNECTED = 1

# State of the interface
wlan_interface_state_connected = 1

# Return codes
ERROR_SUCCESS = 0

# Client versions
CLIENT_VERSION_WINDOWS_XP_SP3 = 1
CLIENT_VERSION_WINDOWS_VISTA_OR_LATER = 2

# Values of wireless LAN authentication algorithm
DOT11_AUTH_ALGO_80211_OPEN = 1
DOT11_AUTH_ALGO_80211_SHARED_KEY = 2
DOT11_AUTH_ALGO_WPA = 3
DOT11_AUTH_ALGO_WPA_PSK = 4
DOT11_AUTH_ALGO_WPA_NONE = 5
DOT11_AUTH_ALGO_RSNA = 6
DOT11_AUTH_ALGO_RSNA_PSK = 7
DOT11_AUTH_ALGO_IHV_START = 0x80000000
DOT11_AUTH_ALGO_IHV_END = 0xffffffff

class DOT11_SSID(Structure):
_fields_ = [
("SSIDLength", c_ulong),
("SSID", c_char * 32),
]

class WLAN_CONNECTION_NOTIFICATION_DATA(Structure):
_fields_ = [
("wlanConnectionMode", c_uint),
("strProfileName", c_wchar * 256),
("dot11Ssid", DOT11_SSID),
("dot11BssType", c_uint),
("bSecurityEnabled", BOOL),
("wlanReasonCode", DWORD),
("dwFlags", DWORD),
("strProfileXml", c_wchar * 1),
]

class WLAN_NOTIFICATION_DATA(Structure):
_fields_ = [
("NotificationSource", DWORD),
("NotificationCode", DWORD),
("InterfaceGuid", GUID),
("dwDataSize", DWORD),
("pData", c_void_p),
]

class WLAN_AVAILABLE_NETWORK(Structure):
_fields_ = [
("ProfileName", c_wchar * 256),
("dot11Ssid", DOT11_SSID),
("dot11BssType", c_uint),
("NumberOfBssids", c_ulong),
("NetworkConnectable", BOOL),
("wlanNotConnectableReason", DWORD),
("NumberOfPhyTypes", c_ulong),
("dot11PhyTypes", c_uint * 8),
("MorePhyTypes", BOOL),
("wlanSignalQuality", c_ulong),
("SecurityEnabled", BOOL),
("dot11DefaultAuthAlgorithm", c_uint),
("dot11DefaultCipherAlgorithm", c_uint),
("Flags", DWORD),
("Reserved", DWORD),
]

class WLAN_AVAILABLE_NETWORK_LIST(Structure):
_fields_ = [
("NumberOfItems", DWORD),
("Index", DWORD),
("Network", WLAN_AVAILABLE_NETWORK * 1),
]

class WLAN_INTERFACE_INFO(Structure):
_fields_ = [
("InterfaceGuid", GUID),
("strInterfaceDescription", c_wchar * 256),
("isState", c_uint),
]

class WLAN_INTERFACE_INFO_LIST(Structure):
_fields_ = [
("NumberOfItems", DWORD),
("Index", DWORD),
("InterfaceInfo", WLAN_INTERFACE_INFO * 1),
]

WLAN_NOTIFICATION_CALLBACK = CFUNCTYPE(None, POINTER(WLAN_NOTIFICATION_DATA), POINTER(c_void_p))

def errcheck(result, func, args):
if result != ERROR_SUCCESS:
raise WinError(c_long(result).value)
return result

def WlanOpenHandle(dwClientVersion, pReserved, pdwNegotiatedVersion, phClientHandle):
""" The WlanOpenHandle function opens a connection to the server. """
wlanapi.WlanOpenHandle.errcheck = errcheck
wlanapi.WlanOpenHandle.argtypes = [DWORD, c_void_p, POINTER(DWORD), POINTER(HANDLE)]
wlanapi.WlanOpenHandle.restype = DWORD
return wlanapi.WlanOpenHandle(dwClientVersion, pReserved, pdwNegotiatedVersion, phClientHandle)

def WlanEnumInterfaces(hClientHandle, pReserved, ppInterfaceList):
""" The WlanEnumInterfaces function enumerates all of the wireless LAN interfaces currently enabled on the local computer. """
wlanapi.WlanEnumInterfaces.errcheck = errcheck
wlanapi.WlanEnumInterfaces.argtypes = [HANDLE, c_void_p, POINTER(POINTER(WLAN_INTERFACE_INFO_LIST))]
wlanapi.WlanEnumInterfaces.restype = DWORD
return wlanapi.WlanEnumInterfaces(hClientHandle, pReserved, ppInterfaceList)

def WlanGetAvailableNetworkList(hClientHandle, pInterfaceGuid, dwFlags, pReserved, ppAvailableNetworkList):
""" The WlanGetAvailableNetworkList function retrieves the list of available networks on a wireless LAN interface. """
wlanapi.WlanGetAvailableNetworkList.errcheck = errcheck
wlanapi.WlanGetAvailableNetworkList.argtypes = [HANDLE, POINTER(GUID), DWORD, c_void_p, POINTER(POINTER(WLAN_AVAILABLE_NETWORK_LIST))]
wlanapi.WlanGetAvailableNetworkList.restype = DWORD
return wlanapi.WlanGetAvailableNetworkList(hClientHandle, pInterfaceGuid, dwFlags, pReserved, ppAvailableNetworkList)

def WlanFreeMemory(pMemory):
""" The WlanFreeMemory function frees memory. Any memory returned from Native Wifi functions must be freed. """
wlanapi.WlanFreeMemory.argtypes = [c_void_p]
wlanapi.WlanFreeMemory(pMemory)

def WlanCloseHandle(hClientHandle, pReserved):
""" The WlanCloseHandle function closes a connection to the server. """
wlanapi.WlanCloseHandle.errcheck = errcheck
wlanapi.WlanCloseHandle.argtypes = [HANDLE, c_void_p]
wlanapi.WlanCloseHandle.restype = DWORD
return wlanapi.WlanCloseHandle(hClientHandle, pReserved)

def WlanRegisterNotification(hClientHandle, dwNotifSource, bIgnoreDuplicate, funcCallback, pCallbackContext, pReserved, pdwPrevNotifSource):
""" The WlanRegisterNotification function is used to register and unregister notifications on all wireless interfaces. """
wlanapi.WlanRegisterNotification.errcheck = errcheck
wlanapi.WlanRegisterNotification.argtypes = [HANDLE, DWORD, BOOL, WLAN_NOTIFICATION_CALLBACK, c_void_p, c_void_p, PDWORD]
wlanapi.WlanRegisterNotification.restype = DWORD
return wlanapi.WlanRegisterNotification(hClientHandle, dwNotifSource, bIgnoreDuplicate, funcCallback, pCallbackContext, pReserved, pdwPrevNotifSource)
4 changes: 2 additions & 2 deletions buildVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ def _(arg):
# Translators: Long description to be shown for this add-on on add-on information from add-ons manager
"addon_description": _("A handy resource monitor to report CPU load, memory usage, battery, disk usage status and more."),
# version
"addon_version": "23.05",
"addon_version": "23.05.1",
# Author(s)
"addon_author": "Alex Hall <[email protected]>, Joseph Lee <[email protected]>, Kefas Lungu <[email protected]>, beqa gozalishvili <[email protected]>, Tuukka Ojala <[email protected]>, Ethin Probst <[email protected]> and other NVDA contributors",
# URL for the add-on documentation support
"addon_url": "https://addons.nvda-project.org/",
# URL for the add-on repository where the source code can be found
"addon_sourceURL": "https://github.com/kefaslungu/resourcemonitor",
"addon_sourceURL": "https://github.com/kefaslungu/resourceMonitor",
# Documentation file name
"addon_docFileName": "readme.html",
# Minimum NVDA version supported (e.g. "2018.3.0", minor version is optional)
Expand Down
7 changes: 7 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ This add-on does not replace task manager and other system information programs
Note on license: this add-on uses Psutil, licensed under 3-Clause BSD License which is compatible with GNU General Public License.

# Version history:
## Version 23.05.1
wlanReporter NVDA-addon is now part of resourceMonitor!

* The old way of checking for wireless connections has been replaced by the windows API from wlanReporter: https://github.com/kvark128/WlanReporter/ .
* After speaking SSID name and strength, NVDA will also now tell you the security type of your network.
* NVDA will now alert you when you connect and disconnect from a wireless network.
* NVDA will now alert you when wireless connections is turned on or off.

## Version 23.05

Expand Down

0 comments on commit 6470dbd

Please sign in to comment.