|
37 | 37 | import exceptions |
38 | 38 | import extensionPoints |
39 | 39 | from fileUtils import getFileVersionInfo |
| 40 | +from typing import Optional |
| 41 | +from systemUtils import getProcessTokenOrigin |
40 | 42 |
|
41 | 43 | # Dictionary of processID:appModule pairs used to hold the currently running modules |
42 | 44 | runningTable: Dict[int, AppModule] = {} |
43 | 45 | #: The process ID of NVDA itself. |
44 | 46 | NVDAProcessID=None |
| 47 | +#: The logon session ID under which NVDA was started. |
| 48 | +NVDAProcessLogonSessionID: Optional[int] = None |
45 | 49 | _importers=None |
46 | 50 | _getAppModuleLock=threading.RLock() |
47 | 51 | #: Notifies when another application is taking foreground. |
@@ -230,8 +234,12 @@ def reloadAppModules(): |
230 | 234 | def initialize(): |
231 | 235 | """Initializes the appModule subsystem. |
232 | 236 | """ |
233 | | - global NVDAProcessID,_importers |
| 237 | + global NVDAProcessID, NVDAProcessLogonSessionID, _importers |
234 | 238 | NVDAProcessID=os.getpid() |
| 239 | + try: |
| 240 | + NVDAProcessLogonSessionID = getProcessTokenOrigin(winKernel.GetCurrentProcess()) |
| 241 | + except WindowsError: |
| 242 | + log.error("Couldn't get NVDAProcessLogonSessionID", exc_info=True) |
235 | 243 | config.addConfigDirsToPythonPackagePath(appModules) |
236 | 244 | _importers=list(pkgutil.iter_importers("appModules.__init__")) |
237 | 245 |
|
@@ -520,6 +528,20 @@ def _get_isWindowsStoreApp(self): |
520 | 528 | self.isWindowsStoreApp = False |
521 | 529 | return self.isWindowsStoreApp |
522 | 530 |
|
| 531 | + def _get_isRunningUnderDifferentLogonSession(self) -> bool: |
| 532 | + """Returns whether the application for this appModule was started under a different logon session. |
| 533 | + This applies to applications started with the Windows runas command |
| 534 | + or when choosing "run as a different user" from an application's (shortcut) context menu. |
| 535 | + """ |
| 536 | + try: |
| 537 | + self.isRunningUnderDifferentLogonSession = ( |
| 538 | + NVDAProcessLogonSessionID != getProcessTokenOrigin(self.processHandle) |
| 539 | + ) |
| 540 | + except WindowsError: |
| 541 | + log.error(f"Couldn't get logon session ID for {self}", exc_info=True) |
| 542 | + self.isRunningUnderDifferentLogonSession = False |
| 543 | + return self.isRunningUnderDifferentLogonSession |
| 544 | + |
523 | 545 | def _get_appArchitecture(self): |
524 | 546 | """Returns the target architecture for the specified app. |
525 | 547 | This is useful for detecting X86/X64 apps running on ARM64 releases of Windows 10. |
|
0 commit comments