Repository: nvaccess/nvda

Issue:
Many scripts not available on secure screen
### Steps to reproduce:
You should have already configured NVDA to be used on Windows secure screen.
1. Start the computer to reach the logon screen
2. Press NVDA+N
3. Press NVDA+1
4. etc.
### Actual behavior:
2. No NVDA menu
3. Help mode is not enabled
### Expected behavior:
2. NVDA menu should open.
3. Help mode should be enabled
### NVDA logs, crash dumps and other attachments:
N/A
### System configuration
#### NVDA installed/portable/running from source:
installed
#### NVDA version:
2022.4beta2
#### Windows version:
Windows 10 2004 (x64) build 19041.388
But same issue seen on other versions of Windows 10.
#### Name and version of other software in use when reproducing the issue:
N/A
#### Other information about your system:
N/A
### Other questions
#### Does the issue still occur after restarting your computer?
Yes
#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Not tried.
But I remember that the issue was not occurring before. I think it has arrived with NVDA2022.4beta2.
#### If NVDA add-ons are disabled, is your problem still occurring?
Not tested.
#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
Yes



Discussion:

Resolving patch:
diff --git a/source/globalVars.py b/source/globalVars.py
--- a/source/globalVars.py
+++ b/source/globalVars.py
@@ -32,6 +32,18 @@ class DefaultAppArgs(argparse.Namespace):
 	language: str = "en"
 	minimal: bool = False
 	secure: bool = False
+	"""
+	When this is True, NVDA is running in secure mode.
+	This is set to True when NVDA starts with the --secure parameter.
+	This is also set to True when NVDA is running on a secure screen
+	(systemUtils._isSecureDesktop() returns True)
+	and the serviceDebug parameter is not set.
+
+	For more information, refer to devDocs/technicalDesignOverview.md 'Logging in secure mode'
+	and the following userGuide sections:
+	 - SystemWideParameters (information on the serviceDebug parameter)
+	 - SecureMode and SecureScreens
+	"""
 	disableAddons: bool = False
 	debugLogging: bool = False
 	noLogging: bool = False
diff --git a/source/systemUtils.py b/source/systemUtils.py
--- a/source/systemUtils.py
+++ b/source/systemUtils.py
@@ -1,11 +1,17 @@
 # -*- coding: UTF-8 -*-
 # A part of NonVisual Desktop Access (NVDA)
-# Copyright (C) 2020-2021 NV Access Limited, Łukasz Golonka
+# Copyright (C) 2020-2022 NV Access Limited, Łukasz Golonka
 # This file may be used under the terms of the GNU General Public License, version 2 or later.
 # For more details see: https://www.gnu.org/licenses/gpl-2.0.html
 
 """ System related functions."""
 import ctypes
+from ctypes import (
+	byref,
+	create_unicode_buffer,
+	sizeof,
+	windll,
+)
 import winKernel
 import shellapi
 import winUser
@@ -142,3 +148,34 @@ def execElevated(path, params=None, wait=False, handleAlreadyElevated=False):
 			return winKernel.GetExitCodeProcess(sei.hProcess)
 		finally:
 			winKernel.closeHandle(sei.hProcess)
+
+
+@functools.lru_cache(maxsize=1)
+def _getDesktopName() -> str:
+	UOI_NAME = 2  # The name of the object, as a string
+	desktop = windll.user32.GetThreadDesktop(windll.kernel32.GetCurrentThreadId())
+	name = create_unicode_buffer(256)
+	windll.user32.GetUserObjectInformationW(
+		desktop,
+		UOI_NAME,
+		byref(name),
+		sizeof(name),
+		None
+	)
+	return name.value
+
+
+def _isSecureDesktop() -> bool:
+	"""
+	When NVDA is running on a secure screen,
+	it is running on the secure desktop.
+	When the serviceDebug parameter is not set,
+	NVDA should run in secure mode when on the secure desktop.
+	globalVars.appArgs.secure being set to True means NVDA is running in secure mode.
+
+	For more information, refer to devDocs/technicalDesignOverview.md 'Logging in secure mode'
+	and the following userGuide sections:
+	 - SystemWideParameters (information on the serviceDebug parameter)
+	 - SecureMode and SecureScreens
+	"""
+	return _getDesktopName() == "Winlogon"
diff --git a/source/winAPI/sessionTracking.py b/source/winAPI/sessionTracking.py
--- a/source/winAPI/sessionTracking.py
+++ b/source/winAPI/sessionTracking.py
@@ -31,6 +31,8 @@
 	Set,
 	Optional,
 )
+
+from systemUtils import _isSecureDesktop
 from winAPI.wtsApi32 import (
 	WTSINFOEXW,
 	WTSQuerySessionInformation,
@@ -152,6 +154,17 @@ def isWindowsLocked() -> bool:
 	Checks if the Window lockscreen is active.
 	Not to be confused with the Windows sign-in screen, a secure screen.
 	"""
+	if _isSecureDesktop():
+		# If this is the Secure Desktop,
+		# we are in secure mode and on a secure screen,
+		# e.g. on the sign-in screen.
+		# _isSecureDesktop may also return True on the lock screen before a user has signed in.
+
+		# For more information, refer to devDocs/technicalDesignOverview.md 'Logging in secure mode'
+		# and the following userGuide sections:
+		# - SystemWideParameters (information on the serviceDebug parameter)
+		# - SecureMode and SecureScreens
+		return False
 	lockStateTracked = _hasLockStateBeenTracked()
 	if lockStateTracked:
 		return WindowsTrackedSession.SESSION_LOCK in _currentSessionStates


Test patch: