Example #1
0
def _isSecureObjectWhileLockScreenActivated(
        obj: NVDAObjects.NVDAObject) -> bool:
    """
	While Windows is locked, Windows 10 and 11 allow for object navigation outside of the lockscreen.
	@return: C{True} if the Windows 10/11 lockscreen is active and C{obj} is outside of the lockscreen.

	According to MS docs, "There is no function you can call to determine whether the workstation is locked."
	https://docs.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-lockworkstation
	"""
    runningAppModules = appModuleHandler.runningTable.values()
    lockAppModule = next(filter(_isLockAppAndAlive, runningAppModules), None)
    if lockAppModule is None:
        return False

    # The LockApp process might be kept alive
    # So determine if it is active, check the foreground window
    foregroundHWND = winUser.getForegroundWindow()
    foregroundProcessId, _threadId = winUser.getWindowThreadProcessID(
        foregroundHWND)

    isLockAppForeground = foregroundProcessId == lockAppModule.processID
    isObjectOutsideLockApp = obj.appModule.processID != foregroundProcessId

    if isLockAppForeground and isObjectOutsideLockApp:
        if log.isEnabledFor(log.DEBUG):
            devInfo = '\n'.join(obj.devInfo)
            log.debug(f"Attempt at navigating to a secure object: {devInfo}")
        return True
    return False
Example #2
0
	def _isUIAWindowHelper(self,hwnd):
		# UIA in NVDA's process freezes in Windows 7 and below
		processID=winUser.getWindowThreadProcessID(hwnd)[0]
		if windll.kernel32.GetCurrentProcessId()==processID:
			return False
		import NVDAObjects.window
		windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
		# A WDAG (Windows Defender Application Guard) Window is always native UIA, even if it doesn't report as such.
		if windowClass=='RAIL_WINDOW':
			return True
		# There are certain window classes that just had bad UIA implementations
		if windowClass in badUIAWindowClassNames:
			return False
		if windowClass=="NetUIHWND":
			parentHwnd=winUser.getAncestor(hwnd,winUser.GA_ROOT)
			# #2816: Outlook 2010 auto complete does not fire enough UIA events, IAccessible is better.
			# #4056: Combo boxes in Office 2010 Options dialogs don't expose a name via UIA, but do via MSAA.
			if winUser.getClassName(parentHwnd) in {"Net UI Tool Window","NUIDialog"}:
				return False
		# allow the appModule for the window to also choose if this window is bad
		appModule=appModuleHandler.getAppModuleFromProcessID(processID)
		if appModule and appModule.isBadUIAWindow(hwnd):
			return False
		# Ask the window if it supports UIA natively
		res=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
		if res:
			# the window does support UIA natively, but
			# Microsoft Word should not use UIA unless we can't inject or the user explicitly chose to use UIA with Microsoft word
			if windowClass=="_WwG" and not (config.conf['UIA']['useInMSWordWhenAvailable'] or not appModule.helperLocalBindingHandle):
				return False
		return bool(res)
def connectConsole(obj):
    global consoleObject, consoleOutputHandle, checkDeadTimer
    #Get the process ID of the console this NVDAObject is fore
    processID, threadID = winUser.getWindowThreadProcessID(obj.windowHandle)
    #Attach NVDA to this console so we can access its text etc
    try:
        wincon.AttachConsole(processID)
    except WindowsError as e:
        log.debugWarning("Could not attach console: %r" % e)
        return False
    wincon.SetConsoleCtrlHandler(_consoleCtrlHandler, True)
    consoleOutputHandle = winKernel.CreateFile(
        u"CONOUT$", winKernel.GENERIC_READ | winKernel.GENERIC_WRITE,
        winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None,
        winKernel.OPEN_EXISTING, 0, None)
    #Register this callback with all the win events we need, storing the given handles for removal later
    for eventID in (winUser.EVENT_CONSOLE_CARET,
                    winUser.EVENT_CONSOLE_UPDATE_REGION,
                    winUser.EVENT_CONSOLE_UPDATE_SIMPLE,
                    winUser.EVENT_CONSOLE_UPDATE_SCROLL,
                    winUser.EVENT_CONSOLE_LAYOUT):
        handle = winUser.setWinEventHook(eventID, eventID, 0,
                                         consoleWinEventHook, 0, 0, 0)
        if not handle:
            raise OSError("could not register eventID %s" % eventID)
        consoleWinEventHookHandles.append(handle)
    consoleObject = obj
    checkDeadTimer = gui.NonReEntrantTimer(_checkDead)
    checkDeadTimer.Start(CHECK_DEAD_INTERVAL)
    return True
 def script_sayCurKeyboardLanguage(self, gesture):
     import winUser
     import scriptHandler
     import ctypes
     import languageHandler
     # Getting the handle of the foreground window.
     curWindow = winUser.getForegroundWindow()
     # Getting the threadID.
     threadID = winUser.getWindowThreadProcessID(curWindow)[1]
     # Getting the keyboard layout iD.
     klID = winUser.getKeyboardLayout(threadID)
     # Extract language ID from klID.
     lID = klID & (2**16 - 1)
     # Getting the current keyboard language description from ctypes.windll.kernel32.GetLocaleInfoW.
     # Some language IDs are not available in the local.windows_locale dictionary, it is best to search their description directly in Windows itself
     buf = ctypes.create_unicode_buffer(1024)
     res = ctypes.windll.kernel32.GetLocaleInfoW(
         lID, languageHandler.LOCALE_SLANGUAGE, buf, 1024)
     desc = buf.value
     defaultOsl = locale.getdefaultlocale()[0]
     repeatCount = scriptHandler.getLastScriptRepeatCount()
     if repeatCount == 0:
         ui.message(desc)
     else:
         ui.message(languageHandler.getLanguageDescription(defaultOsl))
Example #5
0
def processGenericWinEvent(eventID, window, objectID, childID):
    """Converts the win event to an NVDA event,
	Checks to see if this NVDAObject  equals the current focus.
	If all goes well, then the event is queued and we return True
	@param eventID: a win event ID (type)
	@type eventID: integer
	@param window: a win event's window handle
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@returns: True if the event was processed, False otherwise.
	@rtype: boolean
	"""
    # Notify appModuleHandler of this new window
    appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
    # Handle particular events for the special MSAA caret object just as if they were for the focus object
    focus = eventHandler.lastQueuedFocusObject
    if focus and objectID == winUser.OBJID_CARET and eventID in (
            winUser.EVENT_OBJECT_LOCATIONCHANGE, winUser.EVENT_OBJECT_SHOW):
        NVDAEvent = ("caret", focus)
    else:
        NVDAEvent = winEventToNVDAEvent(eventID, window, objectID, childID)
        if not NVDAEvent:
            return False
    if NVDAEvent[0] == "nameChange" and objectID == winUser.OBJID_CURSOR:
        mouseHandler.updateMouseShape(NVDAEvent[1].name)
        return
    if NVDAEvent[1] == focus:
        NVDAEvent = (NVDAEvent[0], focus)
    eventHandler.queueEvent(*NVDAEvent)
    return True
Example #6
0
def terminateRunningNVDA(window):
    processID, threadID = winUser.getWindowThreadProcessID(window)
    winUser.PostMessage(window, winUser.WM_QUIT, 0, 0)
    h = winKernel.openProcess(winKernel.SYNCHRONIZE, False, processID)
    if not h:
        # The process is already dead.
        return
    try:
        res = winKernel.waitForSingleObject(h, 4000)
        if res == 0:
            # The process terminated within the timeout period.
            return
    finally:
        winKernel.closeHandle(h)

    # The process is refusing to exit gracefully, so kill it forcefully.
    h = winKernel.openProcess(
        winKernel.PROCESS_TERMINATE | winKernel.SYNCHRONIZE, False, processID)
    if not h:
        raise OSError("Could not open process for termination")
    try:
        winKernel.TerminateProcess(h, 1)
        winKernel.waitForSingleObject(h, 2000)
    finally:
        winKernel.closeHandle(h)
Example #7
0
	def _isUIAWindowHelper(self,hwnd):
		# UIA in NVDA's process freezes in Windows 7 and below
		processID=winUser.getWindowThreadProcessID(hwnd)[0]
		if windll.kernel32.GetCurrentProcessId()==processID:
			return False
		import NVDAObjects.window
		windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
		# For certain window classes, we always want to use UIA.
		if windowClass in goodUIAWindowClassNames:
			return True
		# allow the appModule for the window to also choose if this window is good
		# An appModule should be able to override bad UIA class names as prescribed by core
		appModule=appModuleHandler.getAppModuleFromProcessID(processID)
		if appModule and appModule.isGoodUIAWindow(hwnd):
			return True
		# There are certain window classes that just had bad UIA implementations
		if windowClass in badUIAWindowClassNames:
			return False
		if windowClass=="NetUIHWND":
			parentHwnd=winUser.getAncestor(hwnd,winUser.GA_ROOT)
			# #2816: Outlook 2010 auto complete does not fire enough UIA events, IAccessible is better.
			# #4056: Combo boxes in Office 2010 Options dialogs don't expose a name via UIA, but do via MSAA.
			if winUser.getClassName(parentHwnd) in {"Net UI Tool Window","NUIDialog"}:
				return False
		# allow the appModule for the window to also choose if this window is bad
		if appModule and appModule.isBadUIAWindow(hwnd):
			return False
		# Ask the window if it supports UIA natively
		res=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
		if res:
			# the window does support UIA natively, but
			# Microsoft Word should not use UIA unless we can't inject or the user explicitly chose to use UIA with Microsoft word
			if windowClass=="_WwG" and not (config.conf['UIA']['useInMSWordWhenAvailable'] or not appModule.helperLocalBindingHandle):
				return False
		return bool(res)
Example #8
0
def processGenericWinEvent(eventID,window,objectID,childID):
	"""Converts the win event to an NVDA event,
	Checks to see if this NVDAObject  equals the current focus.
	If all goes well, then the event is queued and we return True
	@param eventID: a win event ID (type)
	@type eventID: integer
	@param window: a win event's window handle
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@returns: True if the event was processed, False otherwise.
	@rtype: boolean
	"""
	#Notify appModuleHandler of this new window
	appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
	#Handle particular events for the special MSAA caret object just as if they were for the focus object
	focus=eventHandler.lastQueuedFocusObject
	if focus and objectID==winUser.OBJID_CARET and eventID in (winUser.EVENT_OBJECT_LOCATIONCHANGE,winUser.EVENT_OBJECT_SHOW):
		NVDAEvent=("caret",focus)
	else:
		NVDAEvent=winEventToNVDAEvent(eventID,window,objectID,childID)
		if not NVDAEvent:
			return False
	if NVDAEvent[0]=="nameChange" and objectID==winUser.OBJID_CURSOR:
		mouseHandler.updateMouseShape(NVDAEvent[1].name)
		return
	if NVDAEvent[1]==focus:
		NVDAEvent=(NVDAEvent[0],focus)
	eventHandler.queueEvent(*NVDAEvent)
	return True
Example #9
0
 def _isUIAWindowHelper(self, hwnd):
     # UIA in NVDA's process freezes in Windows 7 and below
     processID = winUser.getWindowThreadProcessID(hwnd)[0]
     if windll.kernel32.GetCurrentProcessId() == processID:
         return False
     import NVDAObjects.window
     windowClass = NVDAObjects.window.Window.normalizeWindowClassName(
         winUser.getClassName(hwnd))
     # There are certain window classes that just had bad UIA implementations
     if windowClass in badUIAWindowClassNames:
         return False
     if windowClass == "NetUIHWND":
         parentHwnd = winUser.getAncestor(hwnd, winUser.GA_ROOT)
         # #2816: Outlook 2010 auto complete does not fire enough UIA events, IAccessible is better.
         # #4056: Combo boxes in Office 2010 Options dialogs don't expose a name via UIA, but do via MSAA.
         if winUser.getClassName(parentHwnd) in {
                 "Net UI Tool Window", "NUIDialog"
         }:
             return False
     # allow the appModule for the window to also choose if this window is bad
     appModule = appModuleHandler.getAppModuleFromProcessID(processID)
     if appModule and appModule.isBadUIAWindow(hwnd):
         return False
     # Ask the window if it supports UIA natively
     return windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
Example #10
0
def processFocusWinEvent(window, objectID, childID, force=False):
    """checks to see if the focus win event is not the same as the existing focus,
	then converts the win event to an NVDA event (instantiating an NVDA Object) then calls
	processFocusNVDAEvent. If all is ok it returns True.
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@param force: If True, the shouldAllowIAccessibleFocusEvent property of the object is ignored.
	@type force: boolean
	@returns: True if the focus is valid and was handled, False otherwise.
	@rtype: boolean
	"""
    windowClassName = winUser.getClassName(window)
    # Generally, we must ignore focus on child windows of SDM windows as we only want the SDM MSAA events.
    # However, we don't want to ignore focus if the child ID isn't 0,
    # as this is a child control and the SDM MSAA events don't handle child controls.
    if (childID == 0 and not windowClassName.startswith('bosa_sdm')
            and winUser.getClassName(
                winUser.getAncestor(
                    window, winUser.GA_PARENT)).startswith('bosa_sdm')):
        return False
    # Notify appModuleHandler of this new foreground window
    appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
    # If Java access bridge is running, and this is a java window, then pass it to java and forget about it
    if (childID == 0 and objectID == winUser.OBJID_CLIENT
            and JABHandler.isRunning and JABHandler.isJavaWindow(window)):
        JABHandler.event_enterJavaWindow(window)
        return True
    # Convert the win event to an NVDA event
    NVDAEvent = winEventToNVDAEvent(winUser.EVENT_OBJECT_FOCUS,
                                    window,
                                    objectID,
                                    childID,
                                    useCache=False)
    if not NVDAEvent:
        return False
    eventName, obj = NVDAEvent
    if ((childID == 0 and obj.IAccessibleRole == oleacc.ROLE_SYSTEM_LIST)
            or (objectID == winUser.OBJID_CLIENT
                and "SysListView32" in obj.windowClassName)):
        # Some controls incorrectly fire focus on child ID 0, even when there is a child with focus.
        try:
            realChildID = obj.IAccessibleObject.accFocus
        except:  # noqa: E722 Bare except
            realChildID = None
        if isinstance(realChildID,
                      int) and realChildID > 0 and realChildID != childID:
            realObj = NVDAObjects.IAccessible.IAccessible(
                IAccessibleObject=obj.IAccessibleObject,
                IAccessibleChildID=realChildID,
                event_windowHandle=window,
                event_objectID=objectID,
                event_childID=realChildID)
            if realObj:
                obj = realObj
    return processFocusNVDAEvent(obj, force=force)
Example #11
0
	def prePopup(self):
		"""Prepare for a popup.
		This should be called before any dialog or menu which should pop up for the user.
		L{postPopup} should be called after the dialog or menu has been shown.
		@postcondition: A dialog or menu may be shown.
		"""
		if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != os.getpid():
			# This process is not the foreground process, so bring it to the foreground.
			self.Raise()
Example #12
0
 def _isUIAWindowHelper(self, hwnd):
     # UIA in NVDA's process freezes in Windows 7 and below
     processID = winUser.getWindowThreadProcessID(hwnd)[0]
     if windll.kernel32.GetCurrentProcessId() == processID:
         return False
     import NVDAObjects.window
     windowClass = NVDAObjects.window.Window.normalizeWindowClassName(
         winUser.getClassName(hwnd))
     # For certain window classes, we always want to use UIA.
     if windowClass in goodUIAWindowClassNames:
         return True
     # allow the appModule for the window to also choose if this window is good
     # An appModule should be able to override bad UIA class names as prescribed by core
     appModule = appModuleHandler.getAppModuleFromProcessID(processID)
     if appModule and appModule.isGoodUIAWindow(hwnd):
         return True
     # There are certain window classes that just had bad UIA implementations
     if windowClass in badUIAWindowClassNames:
         return False
     # allow the appModule for the window to also choose if this window is bad
     if appModule and appModule.isBadUIAWindow(hwnd):
         return False
     # Ask the window if it supports UIA natively
     res = windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
     if res:
         # the window does support UIA natively, but
         # MS Word documents now have a very usable UI Automation implementation. However,
         # Builds of MS Office 2016 before build 9000 or so had bugs which we cannot work around.
         # Therefore refuse to use UIA for builds earlier than this, if we can inject in-process.
         if (
                 # An MS Word document window
                 windowClass == "_WwG"
                 # Disabling is only useful if we can inject in-process (and use our older code)
                 and appModule.helperLocalBindingHandle
                 # Allow the user to explisitly force UIA support for MS Word documents no matter the Office version
                 and not config.conf['UIA']['useInMSWordWhenAvailable']):
             # We can only safely check the version of known Office apps using the Word document control, as we know their versioning scheme.
             # But if the Word Document control is used in other unknown apps we should just use UIA if it has been implemented.
             if appModule.appName not in ('outlook', 'winword', 'excel'):
                 log.debugWarning(
                     "Unknown application using MS Word document control: %s"
                     % appModule.appName)
                 return True
             try:
                 versionMajor, versionMinor, versionBuild, versionPatch = [
                     int(x) for x in appModule.productVersion.split('.')
                 ]
             except Exception as e:
                 log.error("Error parsing version information %s, %s" %
                           (appModule.productVersion, e))
                 return True
             if (versionMajor < minMSWordUIAVersion.major
                     or versionMajor == minMSWordUIAVersion.major
                     and versionMinor == minMSWordUIAVersion.minor
                     and versionBuild < minMSWordUIAVersion.build):
                 return False
     return bool(res)
Example #13
0
def getKeyboardLayout():
    curWindow = winUser.getForegroundWindow()
    threadID = winUser.getWindowThreadProcessID(curWindow)[1]
    klID = winUser.getKeyboardLayout(threadID)
    lID = klID & (2**16 - 1)
    try:
        localeName = locale.windows_locale[lID]
    except KeyError:
        localeName = None
    return localeName
Example #14
0
    def prePopup(self):
        """Prepare for a popup.
		This should be called before any dialog or menu which should pop up for the user.
		L{postPopup} should be called after the dialog or menu has been shown.
		@postcondition: A dialog or menu may be shown.
		"""
        if winUser.getWindowThreadProcessID(
                winUser.getForegroundWindow())[0] != os.getpid():
            # This process is not the foreground process, so bring it to the foreground.
            self.Raise()
Example #15
0
 def getKeyboardLanguage(self):
     # Code borrowed from sayCurrentKeyboardLanguage add-on, by Abdel:
     # https://github.com/abdel792/sayCurrentKeyboardLanguage
     # Getting the handle of the foreground window.
     curWindow = winUser.getForegroundWindow()
     # Getting the threadID.
     threadID = winUser.getWindowThreadProcessID(curWindow)[1]
     # Getting the keyboard layout iD.
     klID = winUser.getKeyboardLayout(threadID)
     # Extract language ID from klID.
     lID = klID & (2**16 - 1)
     return lID
Example #16
0
def shouldAcceptEvent(eventName, windowHandle=None):
	"""Check whether an event should be accepted from a platform API.
	Creating NVDAObjects and executing events can be expensive
	and might block the main thread noticeably if the object is slow to respond.
	Therefore, this should be used before NVDAObject creation to filter out any unnecessary events.
	A platform API handler may do its own filtering before this.
	"""
	if not windowHandle:
		# We can't filter without a window handle.
		return True
	key = (eventName,
		winUser.getWindowThreadProcessID(windowHandle)[0],
		winUser.getClassName(windowHandle))
	if key in _acceptEvents:
		return True
	if eventName == "valueChange" and config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]:
		return True
	if eventName == "show":
		# Only accept 'show' events for specific cases, as otherwise we get flooded.
		return winUser.getClassName(windowHandle) in (
			"Frame Notification Bar", # notification bars
			"tooltips_class32", # tooltips
			"mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates
			"TTrayAlert", # 5405: Skype
		)
	if eventName == "reorder":
		# Prevent another flood risk.
		return winUser.getClassName(windowHandle) == "TTrayAlert" # #4841: Skype
	if eventName == "alert" and winUser.getClassName(winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass":
		# Toast notifications.
		return True
	if eventName in ("menuEnd", "switchEnd", "desktopSwitch"):
		# #5302, #5462: These events can be fired on the desktop window
		# or windows that would otherwise be blocked.
		# Platform API handlers will translate these events to focus events anyway,
		# so we must allow them here.
		return True
	if windowHandle == winUser.getDesktopWindow():
		# #5595: Events for the cursor get mapped to the desktop window.
		return True

	fg = winUser.getForegroundWindow()
	if (winUser.isDescendantWindow(fg, windowHandle)
			# #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus.
			or winUser.isDescendantWindow(fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))):
		# This is for the foreground application.
		return True
	if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST
			or winUser.user32.GetWindowLongW(winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST):
		# This window or its root is a topmost window.
		# This includes menus, combo box pop-ups and the task switching list.
		return True
	return False
Example #17
0
	def isUIAWindow(self,hwnd):
		now=time.time()
		v=self.UIAWindowHandleCache.get(hwnd,None)
		if not v or (now-v[1])>0.5:
			if windll.kernel32.GetCurrentProcessId()==winUser.getWindowThreadProcessID(hwnd)[0]:
				isUIA=False
			elif winUser.getClassName(hwnd) in badUIAWindowClassNames:
				isUIA=False
			else:
				isUIA=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
			self.UIAWindowHandleCache[hwnd]=(isUIA,now)
			return isUIA
		return v[0]
Example #18
0
	def isUIAWindow(self,hwnd):
		now=time.time()
		v=self.UIAWindowHandleCache.get(hwnd,None)
		if not v or (now-v[1])>0.5:
			import NVDAObjects.window
			if windll.kernel32.GetCurrentProcessId()==winUser.getWindowThreadProcessID(hwnd)[0]:
				isUIA=False
			elif NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd)) in badUIAWindowClassNames:
				isUIA=False
			else:
				isUIA=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
			self.UIAWindowHandleCache[hwnd]=(isUIA,now)
			return isUIA
		return v[0]
Example #19
0
def shouldAcceptEvent(eventName, windowHandle=None):
	"""Check whether an event should be accepted from a platform API.
	Creating NVDAObjects and executing events can be expensive
	and might block the main thread noticeably if the object is slow to respond.
	Therefore, this should be used before NVDAObject creation to filter out any unnecessary events.
	A platform API handler may do its own filtering before this.
	"""
	if not windowHandle:
		# We can't filter without a window handle.
		return True
	key = (eventName,
		winUser.getWindowThreadProcessID(windowHandle)[0],
		winUser.getClassName(windowHandle))
	if key in _acceptEvents:
		return True
	if eventName == "valueChange" and config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]:
		return True
	if eventName == "show":
		# Only accept 'show' events for specific cases, as otherwise we get flooded.
		return winUser.getClassName(windowHandle) in (
			"Frame Notification Bar", # notification bars
			"tooltips_class32", # tooltips
			"mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates
			"TTrayAlert", # 5405: Skype
		)
	if eventName == "reorder":
		# Prevent another flood risk.
		return winUser.getClassName(windowHandle) == "TTrayAlert" # #4841: Skype
	if eventName == "alert" and winUser.getClassName(winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass":
		# Toast notifications.
		return True
	if eventName in ("menuEnd", "switchEnd", "desktopSwitch"):
		# #5302, #5462: These events can be fired on the desktop window
		# or windows that would otherwise be blocked.
		# Platform API handlers will translate these events to focus events anyway,
		# so we must allow them here.
		return True

	fg = winUser.getForegroundWindow()
	if (winUser.isDescendantWindow(fg, windowHandle)
			# #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus.
			or winUser.isDescendantWindow(fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))):
		# This is for the foreground application.
		return True
	if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST
			or winUser.user32.GetWindowLongW(winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST):
		# This window or its root is a topmost window.
		# This includes menus, combo box pop-ups and the task switching list.
		return True
	return False
Example #20
0
	def prePopup(self):
		"""Prepare for a popup.
		This should be called before any dialog or menu which should pop up for the user.
		L{postPopup} should be called after the dialog or menu has been shown.
		@postcondition: A dialog or menu may be shown.
		"""
		nvdaPid = os.getpid()
		focus = api.getFocusObject()
		if focus.processID != nvdaPid:
			self.prevFocus = focus
			self.prevFocusAncestors = api.getFocusAncestors()
		if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != nvdaPid:
			# This process is not the foreground process, so bring it to the foreground.
			self.Raise()
Example #21
0
	def prePopup(self):
		"""Prepare for a popup.
		This should be called before any dialog or menu which should pop up for the user.
		L{postPopup} should be called after the dialog or menu has been shown.
		@postcondition: A dialog or menu may be shown.
		"""
		nvdaPid = os.getpid()
		focus = api.getFocusObject()
		if focus.processID != nvdaPid:
			self.prevFocus = focus
			self.prevFocusAncestors = api.getFocusAncestors()
		if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != nvdaPid:
			# This process is not the foreground process, so bring it to the foreground.
			self.Raise()
Example #22
0
	def kwargsFromSuper(cls,kwargs,relation=None):
		windowHandle=None
		if relation in ('focus','foreground'):
			windowHandle=winUser.getForegroundWindow()
			if not windowHandle: windowHandle=winUser.getDesktopWindow()
			if windowHandle and relation=="focus":
				threadID=winUser.getWindowThreadProcessID(windowHandle)[1]
				threadInfo=winUser.getGUIThreadInfo(threadID)
				if threadInfo.hwndFocus: windowHandle=threadInfo.hwndFocus
		elif isinstance(relation,tuple):
			windowHandle=_windowFromPoint(ctypes.wintypes.POINT(relation[0],relation[1]))
		if not windowHandle:
			return False
		kwargs['windowHandle']=windowHandle
		return True
Example #23
0
	def kwargsFromSuper(cls,kwargs,relation=None):
		windowHandle=None
		if relation in ('focus','foreground'):
			windowHandle=winUser.getForegroundWindow()
			if not windowHandle: windowHandle=winUser.getDesktopWindow()
			if windowHandle and relation=="focus":
				threadID=winUser.getWindowThreadProcessID(windowHandle)[1]
				threadInfo=winUser.getGUIThreadInfo(threadID)
				if threadInfo.hwndFocus: windowHandle=threadInfo.hwndFocus
		elif isinstance(relation,tuple):
			windowHandle=_windowFromPoint(ctypes.wintypes.POINT(relation[0],relation[1]))
		if not windowHandle:
			return False
		kwargs['windowHandle']=windowHandle
		return True
Example #24
0
def isArabicKeyboardLayout():
    """
	Test if the keyboard layout is Arabic to avoid an error reported by a user.
	"""
    import locale
    curWindow = winUser.getForegroundWindow()
    threadID = winUser.getWindowThreadProcessID(curWindow)[1]
    klID = winUser.getKeyboardLayout(threadID)
    lID = klID & (2**16 - 1)
    try:
        localeName = locale.windows_locale[lID]
    except KeyError:
        localeName = None
    if localeName and localeName.startswith("ar_"):
        return True
    return False
Example #25
0
def _shouldRecoverAfterMinTimeout():
	info=winUser.getGUIThreadInfo(0)
	#If hwndFocus is 0, then the OS is clearly busy and we don't want to timeout prematurely.
	if not info.hwndFocus: return False
	# Import late to avoid circular import.
	import api
	#If a system menu has been activated but NVDA's focus is not yet in the menu then use min timeout
	if info.flags&winUser.GUI_SYSTEMMENUMODE and info.hwndMenuOwner and api.getFocusObject().windowClassName!='#32768':
		return True 
	if winUser.getClassName(info.hwndFocus) in safeWindowClassSet:
		return False
	if not winUser.isDescendantWindow(info.hwndActive, api.getFocusObject().windowHandle):
		# The foreground window has changed.
		return True
	newHwnd=info.hwndFocus
	newThreadID=winUser.getWindowThreadProcessID(newHwnd)[1]
	return newThreadID!=api.getFocusObject().windowThreadID
def processFocusWinEvent(window,objectID,childID,force=False):
	"""checks to see if the focus win event is not the same as the existing focus, 
	then converts the win event to an NVDA event (instanciating an NVDA Object) then calls processFocusNVDAEvent. If all is ok it returns True.
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@param force: If True, the shouldAllowIAccessibleFocusEvent property of the object is ignored.
	@type force: boolean
	@returns: True if the focus is valid and was handled, False otherwise.
	@rtype: boolean
	"""
	windowClassName=winUser.getClassName(window)
	# Generally, we must ignore focus on child windows of SDM windows as we only want the SDM MSAA events.
	# However, we don't want to ignore focus if the child ID isn't 0,
	# as this is a child control and the SDM MSAA events don't handle child controls.
	if childID==0 and not windowClassName.startswith('bosa_sdm') and winUser.getClassName(winUser.getAncestor(window,winUser.GA_PARENT)).startswith('bosa_sdm'):
		return False
	rootWindow=winUser.getAncestor(window,winUser.GA_ROOT)
	# If this window is not within the foreground window and this window or its root window is not a popup window, and this window's root window is not the highest in the z-order
	if not winUser.isDescendantWindow(winUser.getForegroundWindow(),window) and not (winUser.getWindowStyle(window) & winUser.WS_POPUP or winUser.getWindowStyle(rootWindow)&winUser.WS_POPUP) and winUser.getPreviousWindow(rootWindow)!=0: 
		# This is a focus event from a background window, so ignore it.
		return False
	#Notify appModuleHandler of this new foreground window
	appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
	#If Java access bridge is running, and this is a java window, then pass it to java and forget about it
	if JABHandler.isRunning and JABHandler.isJavaWindow(window):
		JABHandler.event_enterJavaWindow(window)
		return True
	#Convert the win event to an NVDA event
	NVDAEvent=winEventToNVDAEvent(winUser.EVENT_OBJECT_FOCUS,window,objectID,childID,useCache=False)
	if not NVDAEvent:
		return False
	eventName,obj=NVDAEvent
	if (childID==0 and obj.IAccessibleRole==oleacc.ROLE_SYSTEM_LIST) or (objectID==winUser.OBJID_CLIENT and "SysListView32" in obj.windowClassName):
		# Some controls incorrectly fire focus on child ID 0, even when there is a child with focus.
		try:
			realChildID=obj.IAccessibleObject.accFocus
		except:
			realChildID=None
		if isinstance(realChildID,int) and realChildID>0 and realChildID!=childID:
			realObj=NVDAObjects.IAccessible.IAccessible(IAccessibleObject=obj.IAccessibleObject,IAccessibleChildID=realChildID,event_windowHandle=window,event_objectID=objectID,event_childID=realChildID)
			if realObj:
				obj=realObj
	return processFocusNVDAEvent(obj,force=force)
Example #27
0
def GetProcessHandleFromHwnd(windowHandle):
    """Retreaves a process handle of the process who owns the window.
	If Windows Vista, uses GetProcessHandleFromHwnd found in oleacc.dll which allows a client with UIAccess to open a process who is elevated.
	if older than Windows Vista, just uses OpenProcess from user32.dll instead.
	@param windowHandle: a window of a process you wish to retreave a process handle for
	@type windowHandle: integer
	@returns: a process handle with read, write and operation access
	@rtype: integer
	"""
    try:
        return oledll.oleacc.GetProcessHandleFromHwnd(windowHandle)
    except:
        import winKernel
        return winKernel.openProcess(
            winKernel.PROCESS_VM_READ | winKernel.PROCESS_VM_WRITE
            | winKernel.PROCESS_VM_OPERATION, False,
            winUser.getWindowThreadProcessID(windowHandle)[0])
Example #28
0
def processForegroundWinEvent(window, objectID, childID):
    """checks to see if the foreground win event is not the same as the existing focus or any of its parents,
	then converts the win event to an NVDA event (instantiating an NVDA Object) and then checks the NVDAObject
	against the existing focus object.
	If all is ok it queues the foreground event to NVDA and returns True.
	@param window: a win event's window handle
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@returns: True if the foreground was processed, False otherwise.
	@rtype: boolean
	"""
    # Ignore foreground events on windows that aren't the current foreground window
    if window != winUser.getForegroundWindow():
        return False
    # If there is a pending gainFocus, it will handle the foreground object.
    oldFocus = eventHandler.lastQueuedFocusObject
    # If this foreground win event's window is an ancestor of the existing focus's window, then ignore it
    if (isinstance(oldFocus, NVDAObjects.window.Window)
            and winUser.isDescendantWindow(window, oldFocus.windowHandle)):
        return False
    # If the existing focus has the same win event params as these, then ignore this event
    if (isinstance(oldFocus, NVDAObjects.IAccessible.IAccessible)
            and window == oldFocus.event_windowHandle
            and objectID == oldFocus.event_objectID
            and childID == oldFocus.event_childID):
        return False
    # Notify appModuleHandler of this new foreground window
    appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
    # If Java access bridge is running, and this is a java window, then pass it to java and forget about it
    if JABHandler.isRunning and JABHandler.isJavaWindow(window):
        JABHandler.event_enterJavaWindow(window)
        return True
    # Convert the win event to an NVDA event
    NVDAEvent = winEventToNVDAEvent(winUser.EVENT_SYSTEM_FOREGROUND,
                                    window,
                                    objectID,
                                    childID,
                                    useCache=False)
    if not NVDAEvent:
        return False
    eventHandler.queueEvent(*NVDAEvent)
    return True
Example #29
0
def requestWSRShowHideEvents(fn=None):
	global requestedWSRShowHideEvents, hookId, eventCallback, wsrPanelHiddenFunction
	if fn is None:
		fn = wsrPanelHiddenFunction
	else:
		wsrPanelHiddenFunction = fn
	if requestedWSRShowHideEvents:
		return
	try:
		hwnd = winUser.FindWindow(u"MS:SpeechTopLevel", None)
	except:
		hwnd = None
	if hwnd:
		pid, tid = winUser.getWindowThreadProcessID(hwnd)
		eventHandler.requestEvents(eventName='show', processId=pid, windowClassName='#32770')
		eventCallback = make_callback(fn)
		hookId = winUser.setWinEventHook(win32con.EVENT_OBJECT_HIDE, win32con.EVENT_OBJECT_HIDE, 0, eventCallback, pid, 0, 0)
		requestedWSRShowHideEvents = True
Example #30
0
def _shouldRecoverAfterMinTimeout():
	info=winUser.getGUIThreadInfo(0)
	if not info.hwndFocus:
		# The foreground thread is frozen or there is no foreground thread (probably due to a freeze elsewhere).
		return True
	# Import late to avoid circular import.
	import api
	#If a system menu has been activated but NVDA's focus is not yet in the menu then use min timeout
	if info.flags&winUser.GUI_SYSTEMMENUMODE and info.hwndMenuOwner and api.getFocusObject().windowClassName!='#32768':
		return True 
	if winUser.getClassName(info.hwndFocus) in safeWindowClassSet:
		return False
	if not winUser.isDescendantWindow(info.hwndActive, api.getFocusObject().windowHandle):
		# The foreground window has changed.
		return True
	newHwnd=info.hwndFocus
	newThreadID=winUser.getWindowThreadProcessID(newHwnd)[1]
	return newThreadID!=api.getFocusObject().windowThreadID
Example #31
0
def _shouldRecoverAfterMinTimeout():
	info=winUser.getGUIThreadInfo(0)
	if not info.hwndFocus:
		# The foreground thread is frozen or there is no foreground thread (probably due to a freeze elsewhere).
		return True
	# Import late to avoid circular import.
	import api
	#If a system menu has been activated but NVDA's focus is not yet in the menu then use min timeout
	if info.flags&winUser.GUI_SYSTEMMENUMODE and info.hwndMenuOwner and api.getFocusObject().windowClassName!='#32768':
		return True 
	if winUser.getClassName(info.hwndFocus) in safeWindowClassSet:
		return False
	if not winUser.isDescendantWindow(info.hwndActive, api.getFocusObject().windowHandle):
		# The foreground window has changed.
		return True
	newHwnd=info.hwndFocus
	newThreadID=winUser.getWindowThreadProcessID(newHwnd)[1]
	return newThreadID!=api.getFocusObject().windowThreadID
def requestWSRShowHideEvents(fn=None):
	global requestedWSRShowHideEvents, hookId, eventCallback, wsrPanelHiddenFunction
	if fn is None:
		fn = wsrPanelHiddenFunction
	else:
		wsrPanelHiddenFunction = fn
	if requestedWSRShowHideEvents:
		return
	try:
		hwnd = winUser.FindWindow(u"MS:SpeechTopLevel", None)
	except:
		hwnd = None
	if hwnd:
		pid, tid = winUser.getWindowThreadProcessID(hwnd)
		eventHandler.requestEvents(eventName='show', processId=pid, windowClassName='#32770')
		eventCallback = make_callback(fn)
		hookId = winUser.setWinEventHook(winUser.EVENT_OBJECT_HIDE, winUser.EVENT_OBJECT_HIDE, 0, eventCallback, pid, 0, 0)
		requestedWSRShowHideEvents = True
Example #33
0
	def prePopup(self):
		"""Prepare for a popup.
		This should be called before any dialog or menu which should pop up for the user.
		L{postPopup} should be called after the dialog or menu has been shown.
		@postcondition: A dialog or menu may be shown.
		"""
		focus = api.getFocusObject()
		# Do not set prevFocus if the focus is on a control rendered by NVDA itself, such as the NVDA menu.
		# This allows to refer to the control that had focus before opening the menu while still using NVDA
		# on its own controls.
		# The check for NVDA process ID can be bypassed by setting the optional attribute
		# L{isPrevFocusOnNvdaPopup} to L{True} when a NVDA dialog offers customizable bound gestures,
		# eg. the NVDA Python Console.
		if focus.processID != globalVars.appPid or getattr(focus, "isPrevFocusOnNvdaPopup", False):
			self.prevFocus = focus
			self.prevFocusAncestors = api.getFocusAncestors()
		if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != globalVars.appPid:
			# This process is not the foreground process, so bring it to the foreground.
			self.Raise()
	def _get_lvAppImageID(self):
		item=LVItemStruct(iItem=self.IAccessibleChildID-1,mask=LVIF_IMAGE)
		(processID,threadID)=winUser.getWindowThreadProcessID(self.windowHandle)
		processHandle=self.processHandle
		internalItem=winKernel.virtualAllocEx(processHandle,None,sizeof(LVItemStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
		winKernel.writeProcessMemory(processHandle,internalItem,byref(item),sizeof(LVItemStruct),None)
		winUser.sendMessage(self.windowHandle,LVM_GETITEM,0,internalItem)
		dispInfo=NMLVDispInfoStruct()
		dispInfo.item=internalItem
		dispInfo.hdr.hwndFrom=self.windowHandle
		dispInfo.hdr.idFrom=self.windowControlID
		dispInfo.hdr.code=LVN_GETDISPINFO
		internalDispInfo=winKernel.virtualAllocEx(processHandle,None,sizeof(NMLVDispInfoStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
		winKernel.writeProcessMemory(processHandle,internalDispInfo,byref(dispInfo),sizeof(NMLVDispInfoStruct),None)
		winUser.sendMessage(self.parent.parent.windowHandle,winUser.WM_NOTIFY,LVN_GETDISPINFO,internalDispInfo)
		winKernel.virtualFreeEx(processHandle,internalDispInfo,0,winKernel.MEM_RELEASE)
		winKernel.readProcessMemory(processHandle,internalItem,byref(item),sizeof(LVItemStruct),None)
		winKernel.virtualFreeEx(processHandle,internalItem,0,winKernel.MEM_RELEASE)
		return item.iImage
def getListGroupInfo(windowHandle,groupIndex):
	(processID,threadID)=winUser.getWindowThreadProcessID(windowHandle)
	processHandle=oleacc.GetProcessHandleFromHwnd(windowHandle)
	localInfo=LVGROUP()
	localInfo.cbSize=sizeof(LVGROUP)
	localInfo.mask=LVGF_HEADER|LVGF_FOOTER|LVGF_STATE|LVGF_ALIGN|LVGF_GROUPID
	localInfo.stateMask=0xffffffff
	remoteInfo=winKernel.virtualAllocEx(processHandle,None,sizeof(LVGROUP),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
	winKernel.writeProcessMemory(processHandle,remoteInfo,byref(localInfo),sizeof(LVGROUP),None)
	messageRes=winUser.sendMessage(windowHandle,LVM_GETGROUPINFOBYINDEX,groupIndex,remoteInfo)
	winKernel.readProcessMemory(processHandle,remoteInfo,byref(localInfo),sizeof(LVGROUP),None)
	winKernel.virtualFreeEx(processHandle,remoteInfo,0,winKernel.MEM_RELEASE)
	localHeader=create_unicode_buffer(localInfo.cchHeader)
	winKernel.readProcessMemory(processHandle,localInfo.pszHeader,localHeader,localInfo.cchHeader*2,None)
	localFooter=create_unicode_buffer(localInfo.cchFooter)
	winKernel.readProcessMemory(processHandle,localInfo.pszFooter,localFooter,localInfo.cchFooter*2,None)
	winKernel.closeHandle(processHandle)
	if messageRes==1:
		return dict(header=localHeader.value,footer=localFooter.value,groupID=localInfo.iGroupId,state=localInfo.state,uAlign=localInfo.uAlign,groupIndex=groupIndex)
	else:
		return None
Example #36
0
	def _isUIAWindowHelper(self,hwnd):
		# UIA in NVDA's process freezes in Windows 7 and below
		processID=winUser.getWindowThreadProcessID(hwnd)[0]
		if windll.kernel32.GetCurrentProcessId()==processID:
			return False
		import NVDAObjects.window
		windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
		# There are certain window classes that just had bad UIA implementations
		if windowClass in badUIAWindowClassNames:
			return False
		if windowClass=="NetUIHWND":
			parentHwnd=winUser.getAncestor(hwnd,winUser.GA_ROOT)
			# #2816: Outlook 2010 auto complete does not fire enough UIA events, IAccessible is better.
			if winUser.getClassName(parentHwnd)=="Net UI Tool Window":
				return False
		# allow the appModule for the window to also choose if this window is bad
		appModule=appModuleHandler.getAppModuleFromProcessID(processID)
		if appModule and appModule.isBadUIAWindow(hwnd):
			return False
		# Ask the window if it supports UIA natively
		return windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
Example #37
0
	def _isUIAWindowHelper(self,hwnd):
		# UIA in NVDA's process freezes in Windows 7 and below
		processID=winUser.getWindowThreadProcessID(hwnd)[0]
		if windll.kernel32.GetCurrentProcessId()==processID:
			return False
		import NVDAObjects.window
		windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
		# For certain window classes, we always want to use UIA.
		if windowClass in goodUIAWindowClassNames:
			return True
		# allow the appModule for the window to also choose if this window is good
		# An appModule should be able to override bad UIA class names as prescribed by core
		appModule=appModuleHandler.getAppModuleFromProcessID(processID)
		if appModule and appModule.isGoodUIAWindow(hwnd):
			return True
		# There are certain window classes that just had bad UIA implementations
		if self._isBadUIAWindowClassName(windowClass):
			return False
		# allow the appModule for the window to also choose if this window is bad
		if appModule and appModule.isBadUIAWindow(hwnd):
			return False
		# Ask the window if it supports UIA natively
		res=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
		if res:
			# the window does support UIA natively, but
			# MS Word documents now have a fairly usable UI Automation implementation. However,
			# Builds of MS Office 2016 before build 9000 or so had bugs which we cannot work around.
			# And even current builds of Office 2016 are still missing enough info from UIA that it is still impossible to switch to UIA completely.
			# Therefore, if we can inject in-process, refuse to use UIA and instead fall back to the MS Word object model.
			if (
				# An MS Word document window 
				windowClass=="_WwG" 
				# Disabling is only useful if we can inject in-process (and use our older code)
				and appModule.helperLocalBindingHandle 
				# Allow the user to explisitly force UIA support for MS Word documents no matter the Office version 
				and not config.conf['UIA']['useInMSWordWhenAvailable']
			):
				return False
		return bool(res)
Example #38
0
	def _isUIAWindowHelper(self,hwnd):
		# UIA in NVDA's process freezes in Windows 7 and below
		processID=winUser.getWindowThreadProcessID(hwnd)[0]
		if windll.kernel32.GetCurrentProcessId()==processID:
			return False
		import NVDAObjects.window
		windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
		# For certain window classes, we always want to use UIA.
		if windowClass in goodUIAWindowClassNames:
			return True
		# allow the appModule for the window to also choose if this window is good
		# An appModule should be able to override bad UIA class names as prescribed by core
		appModule=appModuleHandler.getAppModuleFromProcessID(processID)
		if appModule and appModule.isGoodUIAWindow(hwnd):
			return True
		# There are certain window classes that just had bad UIA implementations
		if windowClass in badUIAWindowClassNames:
			return False
		# allow the appModule for the window to also choose if this window is bad
		if appModule and appModule.isBadUIAWindow(hwnd):
			return False
		# Ask the window if it supports UIA natively
		res=windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
		if res:
			# the window does support UIA natively, but
			# MS Word documents now have a fairly usable UI Automation implementation. However,
			# Builds of MS Office 2016 before build 9000 or so had bugs which we cannot work around.
			# And even current builds of Office 2016 are still missing enough info from UIA that it is still impossible to switch to UIA completely.
			# Therefore, if we can inject in-process, refuse to use UIA and instead fall back to the MS Word object model.
			if (
				# An MS Word document window 
				windowClass=="_WwG" 
				# Disabling is only useful if we can inject in-process (and use our older code)
				and appModule.helperLocalBindingHandle 
				# Allow the user to explisitly force UIA support for MS Word documents no matter the Office version 
				and not config.conf['UIA']['useInMSWordWhenAvailable']
			):
				return False
		return bool(res)
Example #39
0
def connectConsole(obj):
	global consoleObject, consoleOutputHandle, checkDeadTimer
	#Get the process ID of the console this NVDAObject is fore
	processID,threadID=winUser.getWindowThreadProcessID(obj.windowHandle)
	#Attach NVDA to this console so we can access its text etc
	try:
		wincon.AttachConsole(processID)
	except WindowsError as e:
		log.debugWarning("Could not attach console: %r"%e)
		return False
	wincon.SetConsoleCtrlHandler(_consoleCtrlHandler,True)
	consoleOutputHandle=winKernel.CreateFile(u"CONOUT$",winKernel.GENERIC_READ|winKernel.GENERIC_WRITE,winKernel.FILE_SHARE_READ|winKernel.FILE_SHARE_WRITE,None,winKernel.OPEN_EXISTING,0,None)                                                     
	#Register this callback with all the win events we need, storing the given handles for removal later
	for eventID in (winUser.EVENT_CONSOLE_CARET,winUser.EVENT_CONSOLE_UPDATE_REGION,winUser.EVENT_CONSOLE_UPDATE_SIMPLE,winUser.EVENT_CONSOLE_UPDATE_SCROLL,winUser.EVENT_CONSOLE_LAYOUT):
		handle=winUser.setWinEventHook(eventID,eventID,0,consoleWinEventHook,0,0,0)
		if not handle:
			raise OSError("could not register eventID %s"%eventID)
		consoleWinEventHookHandles.append(handle)
	consoleObject=obj
	checkDeadTimer=gui.NonReEntrantTimer(_checkDead)
	checkDeadTimer.Start(CHECK_DEAD_INTERVAL)
	return True
Example #40
0
def getWinEventLogInfo(window, objectID, childID, eventID=None, threadID=None):
    """
	Formats the given winEvent parameters into a printable string.
	window, objectID and childID are mandatory,
	but eventID and threadID are optional.
	"""
    windowClassName = winUser.getClassName(window) or "unknown"
    objectIDName = getObjectIDName(objectID)
    processID = winUser.getWindowThreadProcessID(window)[0]
    if processID:
        processName = appModuleHandler.getAppModuleFromProcessID(
            processID).appName
    else:
        processName = "unknown application"
    messageList = []
    if eventID is not None:
        eventName = getWinEventName(eventID)
        messageList.append(f"{eventName}")
    messageList.append(
        f"window {window} ({windowClassName}), objectID {objectIDName}, childID {childID}, "
        f"process {processID} ({processName})")
    if threadID is not None:
        messageList.append(f"thread {threadID}")
    return ", ".join(messageList)
Example #41
0
def processForegroundWinEvent(window,objectID,childID):
	"""checks to see if the foreground win event is not the same as the existing focus or any of its parents, 
	then converts the win event to an NVDA event (instanciating an NVDA Object) and then checks the NVDAObject against the existing focus object. 
	If all is ok it queues the foreground event to NVDA and returns True.
	@param window: a win event's window handle
	@type window: integer
	@param objectID: a win event's object ID
	@type objectID: integer
	@param childID: a win event's child ID
	@type childID: integer
	@returns: True if the foreground was processed, False otherwise.
	@rtype: boolean
	"""
	#Ignore foreground events on windows that aren't the current foreground window
	if window!=winUser.getForegroundWindow():
		return False
	# If there is a pending gainFocus, it will handle the foreground object.
	oldFocus=eventHandler.lastQueuedFocusObject
	#If this foreground win event's window is an ancestor of the existing focus's window, then ignore it
	if isinstance(oldFocus,NVDAObjects.window.Window) and winUser.isDescendantWindow(window,oldFocus.windowHandle):
		return False
	#If the existing focus has the same win event params as these, then ignore this event
	if isinstance(oldFocus,NVDAObjects.IAccessible.IAccessible) and window==oldFocus.event_windowHandle and objectID==oldFocus.event_objectID and childID==oldFocus.event_childID:
		return False
	#Notify appModuleHandler of this new foreground window
	appModuleHandler.update(winUser.getWindowThreadProcessID(window)[0])
	#If Java access bridge is running, and this is a java window, then pass it to java and forget about it
	if JABHandler.isRunning and JABHandler.isJavaWindow(window):
		JABHandler.event_enterJavaWindow(window)
		return True
	#Convert the win event to an NVDA event
	NVDAEvent=winEventToNVDAEvent(winUser.EVENT_SYSTEM_FOREGROUND,window,objectID,childID,useCache=False)
	if not NVDAEvent:
		return False
	eventHandler.queueEvent(*NVDAEvent)
	return True
Example #42
0
def shouldAcceptEvent(eventName, windowHandle=None):
    """Check whether an event should be accepted from a platform API.
	Creating NVDAObjects and executing events can be expensive
	and might block the main thread noticeably if the object is slow to respond.
	Therefore, this should be used before NVDAObject creation to filter out any unnecessary events.
	A platform API handler may do its own filtering before this.
	"""
    if not windowHandle:
        # We can't filter without a window handle.
        return True
    wClass = winUser.getClassName(windowHandle)
    key = (eventName, winUser.getWindowThreadProcessID(windowHandle)[0],
           wClass)
    if key in _acceptEvents:
        return True
    if eventName == "valueChange" and config.conf["presentation"][
            "progressBarUpdates"]["reportBackgroundProgressBars"]:
        return True
    if eventName == "hide":
        return False
    if eventName == "show":
        # Only accept 'show' events for specific cases, as otherwise we get flooded.
        return wClass in (
            "Frame Notification Bar",  # notification bars
            "tooltips_class32",  # tooltips
            "mscandui21.candidate",
            "mscandui40.candidate",
            "MSCandUIWindow_Candidate",  # IMM candidates
            "TTrayAlert",  # 5405: Skype
        )
    if eventName == "alert" and winUser.getClassName(
            winUser.getAncestor(windowHandle,
                                winUser.GA_PARENT)) == "ToastChildWindowClass":
        # Toast notifications.
        return True
    if eventName in ("menuEnd", "switchEnd", "desktopSwitch"):
        # #5302, #5462: These events can be fired on the desktop window
        # or windows that would otherwise be blocked.
        # Platform API handlers will translate these events to focus events anyway,
        # so we must allow them here.
        return True
    if windowHandle == winUser.getDesktopWindow():
        # #5595: Events for the cursor get mapped to the desktop window.
        return True

    # #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window.
    # However, it does look like they are always  equal to or descendants of the "active" window of the input thread.
    gi = winUser.getGUIThreadInfo(0)
    if wClass.startswith('Windows.UI.Core'):
        if winUser.isDescendantWindow(gi.hwndActive, windowHandle):
            return True

    fg = winUser.getForegroundWindow()
    fgClassName = winUser.getClassName(fg)
    if wClass == "NetUIHWND" and fgClassName in ("Net UI Tool Window Layered",
                                                 "Net UI Tool Window"):
        # #5504: In Office >= 2013 with the ribbon showing only tabs,
        # when a tab is expanded, the window we get from the focus object is incorrect.
        # This window isn't beneath the foreground window,
        # so our foreground application checks fail.
        # Just compare the root owners.
        if winUser.getAncestor(windowHandle,
                               winUser.GA_ROOTOWNER) == winUser.getAncestor(
                                   fg, winUser.GA_ROOTOWNER):
            return True
    if (winUser.isDescendantWindow(fg, windowHandle)
            # #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus.
            or winUser.isDescendantWindow(
                fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))):
        # This is for the foreground application.
        return True
    if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE)
            & winUser.WS_EX_TOPMOST or winUser.user32.GetWindowLongW(
                winUser.getAncestor(windowHandle, winUser.GA_ROOT),
                winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST):
        # This window or its root is a topmost window.
        # This includes menus, combo box pop-ups and the task switching list.
        return True
    # This may be an event for a windowless embedded Chrome document
    # (E.g. Microsoft Loop component).
    if wClass == "Chrome_RenderWidgetHostHWND":
        # The event is for a Chromium document
        if winUser.getClassName(gi.hwndFocus) == "Chrome_WidgetWin_0":
            # The real win32 focus is on a Chrome embedding window.
            # See if we can get from the event's Chromium document to the Chrome embedding window
            # via ancestors in the UIA tree.
            rootWindowHandle = winUser.getAncestor(windowHandle,
                                                   winUser.GA_ROOT)
            import UIAHandler
            try:
                rootElement = UIAHandler.handler.clientObject.elementFromHandle(
                    rootWindowHandle)
            except COMError:
                log.debugWarning(
                    "Could not create UIA element for root of Chromium document",
                    exc_info=True)
            else:
                condition = UIAHandler.handler.clientObject.CreatePropertyCondition(
                    UIAHandler.UIA_NativeWindowHandlePropertyId, gi.hwndFocus)
                try:
                    walker = UIAHandler.handler.clientObject.CreateTreeWalker(
                        condition)
                    ancestorElement = walker.NormalizeElement(rootElement)
                except COMError:
                    log.debugWarning(
                        "Unable to normalize root Chromium element to focused ancestor",
                        exc_info=True)
                    ancestorElement = None
                if ancestorElement:
                    # The real focused window is an ancestor of the Chromium document in the UIA tree.
                    return True
    return False
Example #43
0
def GetProcessHandleFromHwnd(windowHandle):
	"""Retreaves a process handle of the process who owns the window.
	If Windows Vista, uses GetProcessHandleFromHwnd found in oleacc.dll which allows a client with UIAccess to open a process who is elevated.
	if older than Windows Vista, just uses OpenProcess from user32.dll instead.
	@param windowHandle: a window of a process you wish to retreave a process handle for
	@type windowHandle: integer
	@returns: a process handle with read, write and operation access
	@rtype: integer
	"""
	try:
		return oledll.oleacc.GetProcessHandleFromHwnd(windowHandle)
	except:
		import winKernel
		return winKernel.openProcess(winKernel.PROCESS_VM_READ|winKernel.PROCESS_VM_WRITE|winKernel.PROCESS_VM_OPERATION,False,winUser.getWindowThreadProcessID(windowHandle)[0])
Example #44
0
def shouldAcceptEvent(eventName, windowHandle=None):
    """Check whether an event should be accepted from a platform API.
	Creating NVDAObjects and executing events can be expensive
	and might block the main thread noticeably if the object is slow to respond.
	Therefore, this should be used before NVDAObject creation to filter out any unnecessary events.
	A platform API handler may do its own filtering before this.
	"""
    if not windowHandle:
        # We can't filter without a window handle.
        return True
    wClass = winUser.getClassName(windowHandle)
    key = (eventName, winUser.getWindowThreadProcessID(windowHandle)[0],
           wClass)
    if key in _acceptEvents:
        return True
    if eventName == "valueChange" and config.conf["presentation"][
            "progressBarUpdates"]["reportBackgroundProgressBars"]:
        return True
    if eventName == "show":
        # Only accept 'show' events for specific cases, as otherwise we get flooded.
        return wClass in (
            "Frame Notification Bar",  # notification bars
            "tooltips_class32",  # tooltips
            "mscandui21.candidate",
            "mscandui40.candidate",
            "MSCandUIWindow_Candidate",  # IMM candidates
            "TTrayAlert",  # 5405: Skype
        )
    if eventName == "reorder":
        # Prevent another flood risk.
        return wClass == "TTrayAlert"  # #4841: Skype
    if eventName == "alert" and winUser.getClassName(
            winUser.getAncestor(windowHandle,
                                winUser.GA_PARENT)) == "ToastChildWindowClass":
        # Toast notifications.
        return True
    if eventName in ("menuEnd", "switchEnd", "desktopSwitch"):
        # #5302, #5462: These events can be fired on the desktop window
        # or windows that would otherwise be blocked.
        # Platform API handlers will translate these events to focus events anyway,
        # so we must allow them here.
        return True
    if windowHandle == winUser.getDesktopWindow():
        # #5595: Events for the cursor get mapped to the desktop window.
        return True

    # #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window.
    # However, it does look like they are always  equal to or descendants of the "active" window of the input thread.
    if wClass.startswith('Windows.UI.Core'):
        gi = winUser.getGUIThreadInfo(0)
        if winUser.isDescendantWindow(gi.hwndActive, windowHandle):
            return True

    fg = winUser.getForegroundWindow()
    if wClass == "NetUIHWND" and winUser.getClassName(
            fg) == "Net UI Tool Window Layered":
        # #5504: In Office >= 2013 with the ribbon showing only tabs,
        # when a tab is expanded, the window we get from the focus object is incorrect.
        # This window isn't beneath the foreground window,
        # so our foreground application checks fail.
        # Just compare the root owners.
        if winUser.getAncestor(windowHandle,
                               winUser.GA_ROOTOWNER) == winUser.getAncestor(
                                   fg, winUser.GA_ROOTOWNER):
            return True
    if (winUser.isDescendantWindow(fg, windowHandle)
            # #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus.
            or winUser.isDescendantWindow(
                fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))):
        # This is for the foreground application.
        return True
    if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE)
            & winUser.WS_EX_TOPMOST or winUser.user32.GetWindowLongW(
                winUser.getAncestor(windowHandle, winUser.GA_ROOT),
                winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST):
        # This window or its root is a topmost window.
        # This includes menus, combo box pop-ups and the task switching list.
        return True
    return False
Example #45
0
	def _get_windowThreadID(self):
		if hasattr(self,"_processIDThreadID"):
			return self._processIDThreadID[1]
		self._processIDThreadID=winUser.getWindowThreadProcessID(self.windowHandle)
		return self._processIDThreadID[1]
Example #46
0
 def _isUIAWindowHelper(self, hwnd):
     # UIA in NVDA's process freezes in Windows 7 and below
     processID = winUser.getWindowThreadProcessID(hwnd)[0]
     if windll.kernel32.GetCurrentProcessId() == processID:
         return False
     import NVDAObjects.window
     windowClass = NVDAObjects.window.Window.normalizeWindowClassName(
         winUser.getClassName(hwnd))
     # For certain window classes, we always want to use UIA.
     if windowClass in goodUIAWindowClassNames:
         return True
     # allow the appModule for the window to also choose if this window is good
     # An appModule should be able to override bad UIA class names as prescribed by core
     appModule = appModuleHandler.getAppModuleFromProcessID(processID)
     if appModule and appModule.isGoodUIAWindow(hwnd):
         return True
     # There are certain window classes that just had bad UIA implementations
     if self._isBadUIAWindowClassName(windowClass):
         return False
     # allow the appModule for the window to also choose if this window is bad
     if appModule and appModule.isBadUIAWindow(hwnd):
         return False
     if windowClass == "NetUIHWND" and appModule:
         # NetUIHWND is used for various controls in MS Office.
         # IAccessible should be used for NetUIHWND in versions older than 2016
         # Fixes: lack of focus reporting (#4207),
         # Fixes: strange reporting of context menu items(#9252),
         # fixes: not being able to report ribbon sections when they starts with an edit  field (#7067)
         # Note that #7067 is not fixed for Office 2016 and never.
         # Using IAccessible for NetUIHWND controls causes focus changes not to be reported
         # when the ribbon is collapsed.
         # Testing shows that these controls emits proper events but they are ignored by NVDA.
         isOfficeApp = appModule.productName.startswith(
             ("Microsoft Office", "Microsoft Outlook"))
         isOffice2013OrOlder = int(
             appModule.productVersion.split(".")[0]) < 16
         if isOfficeApp and isOffice2013OrOlder:
             parentHwnd = winUser.getAncestor(hwnd, winUser.GA_PARENT)
             while parentHwnd:
                 if winUser.getClassName(parentHwnd) in (
                         "Net UI Tool Window",
                         "MsoCommandBar",
                 ):
                     return False
                 parentHwnd = winUser.getAncestor(parentHwnd,
                                                  winUser.GA_PARENT)
     # Ask the window if it supports UIA natively
     res = windll.UIAutomationCore.UiaHasServerSideProvider(hwnd)
     if res:
         # the window does support UIA natively, but
         # MS Word documents now have a fairly usable UI Automation implementation. However,
         # Builds of MS Office 2016 before build 9000 or so had bugs which we cannot work around.
         # And even current builds of Office 2016 are still missing enough info from UIA that it is still impossible to switch to UIA completely.
         # Therefore, if we can inject in-process, refuse to use UIA and instead fall back to the MS Word object model.
         canUseOlderInProcessApproach = bool(
             appModule.helperLocalBindingHandle)
         if (
                 # An MS Word document window
                 windowClass == "_WwG"
                 # Disabling is only useful if we can inject in-process (and use our older code)
                 and canUseOlderInProcessApproach
                 # Allow the user to explisitly force UIA support for MS Word documents no matter the Office version
                 and not config.conf['UIA']['useInMSWordWhenAvailable']):
             return False
         # Unless explicitly allowed, all Chromium implementations (including Edge) should not be UIA,
         # As their IA2 implementation is still better at the moment.
         elif (
                 windowClass == "Chrome_RenderWidgetHostHWND" and
             (AllowUiaInChromium.getConfig() == AllowUiaInChromium.NO
              # Disabling is only useful if we can inject in-process (and use our older code)
              or (canUseOlderInProcessApproach
                  and AllowUiaInChromium.getConfig() !=
                  AllowUiaInChromium.YES  # Users can prefer to use UIA
                  ))):
             return False
     return bool(res)
Example #47
0
	def _get_windowThreadID(self):
		if hasattr(self,"_processIDThreadID"):
			return self._processIDThreadID[1]
		self._processIDThreadID=winUser.getWindowThreadProcessID(self.windowHandle)
		return self._processIDThreadID[1]
Example #48
0
def shouldAcceptEvent(eventName, windowHandle=None):
	"""Check whether an event should be accepted from a platform API.
	Creating NVDAObjects and executing events can be expensive
	and might block the main thread noticeably if the object is slow to respond.
	Therefore, this should be used before NVDAObject creation to filter out any unnecessary events.
	A platform API handler may do its own filtering before this.
	"""
	if not windowHandle:
		# We can't filter without a window handle.
		return True
	wClass = winUser.getClassName(windowHandle)
	key = (eventName,
		winUser.getWindowThreadProcessID(windowHandle)[0],
		wClass)
	if key in _acceptEvents:
		return True
	if eventName == "valueChange" and config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]:
		return True
	if eventName == "show":
		# Only accept 'show' events for specific cases, as otherwise we get flooded.
		return wClass in (
			"Frame Notification Bar", # notification bars
			"tooltips_class32", # tooltips
			"mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates
			"TTrayAlert", # 5405: Skype
		)
	if eventName == "reorder":
		# Prevent another flood risk.
		return wClass == "TTrayAlert" # #4841: Skype
	if eventName == "alert" and winUser.getClassName(winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass":
		# Toast notifications.
		return True
	if eventName in ("menuEnd", "switchEnd", "desktopSwitch"):
		# #5302, #5462: These events can be fired on the desktop window
		# or windows that would otherwise be blocked.
		# Platform API handlers will translate these events to focus events anyway,
		# so we must allow them here.
		return True
	if windowHandle == winUser.getDesktopWindow():
		# #5595: Events for the cursor get mapped to the desktop window.
		return True

	# #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window.
	# However, it does look like they are always  equal to or descendants of the "active" window of the input thread. 
	if wClass.startswith('Windows.UI.Core'):
		gi=winUser.getGUIThreadInfo(0)
		if winUser.isDescendantWindow(gi.hwndActive,windowHandle):
			return True

	fg = winUser.getForegroundWindow()
	if wClass == "NetUIHWND" and winUser.getClassName(fg) == "Net UI Tool Window Layered":
		# #5504: In Office >= 2013 with the ribbon showing only tabs,
		# when a tab is expanded, the window we get from the focus object is incorrect.
		# This window isn't beneath the foreground window,
		# so our foreground application checks fail.
		# Just compare the root owners.
		if winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER) == winUser.getAncestor(fg, winUser.GA_ROOTOWNER):
			return True
	if (winUser.isDescendantWindow(fg, windowHandle)
			# #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus.
			or winUser.isDescendantWindow(fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))):
		# This is for the foreground application.
		return True
	if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST
			or winUser.user32.GetWindowLongW(winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST):
		# This window or its root is a topmost window.
		# This includes menus, combo box pop-ups and the task switching list.
		return True
	return False