Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support UI Automation within a Windows Defender Application Guard process #7600

Merged
merged 9 commits into from Oct 9, 2017
4 changes: 1 addition & 3 deletions source/NVDAObjects/UIA/__init__.py
Expand Up @@ -817,8 +817,6 @@ def __init__(self,windowHandle=None,UIAElement=None,initialUIACachedPropertyIDs=

UIACachedWindowHandle=UIAElement.cachedNativeWindowHandle
self.UIAIsWindowElement=bool(UIACachedWindowHandle)
if UIACachedWindowHandle:
windowHandle=UIACachedWindowHandle
if not windowHandle:
windowHandle=UIAHandler.handler.getNearestWindowHandle(UIAElement)
if not windowHandle:
Expand Down Expand Up @@ -1136,7 +1134,7 @@ def _get_children(self):
return children
for index in xrange(cachedChildren.length):
e=cachedChildren.getElement(index)
windowHandle=e.cachedNativeWindowHandle or self.windowHandle
windowHandle=self.windowHandle
children.append(self.correctAPIForRelation(UIA(windowHandle=windowHandle,UIAElement=e)))
return children

Expand Down
38 changes: 26 additions & 12 deletions source/_UIAHandler.py
Expand Up @@ -21,6 +21,7 @@
import winUser
import eventHandler
from logHandler import log
import UIAUtils

from comtypes.gen.UIAutomationClient import *

Expand All @@ -45,7 +46,10 @@
HorizontalTextAlignment_Centered=1
HorizontalTextAlignment_Right=2
HorizontalTextAlignment_Justified=3


# The name of the WDAG (Windows Defender Application Guard) process
WDAG_PROCESS_NAME=u'hvsirdpclient'

badUIAWindowClassNames=[
"SysTreeView32",
"WuDuiListView",
Expand Down Expand Up @@ -291,6 +295,9 @@ def _isUIAWindowHelper(self,hwnd):
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
Expand Down Expand Up @@ -320,19 +327,26 @@ def getNearestWindowHandle(self,UIAElement):
# Called previously. Use cached result.
return UIAElement._nearestWindowHandle
try:
window=UIAElement.cachedNativeWindowHandle
processID=UIAElement.cachedProcessID
except COMError:
return None
appModule=appModuleHandler.getAppModuleFromProcessID(processID)
# WDAG (Windows Defender application Guard) UIA elements should be treated as being from a remote machine, and therefore their window handles are completely invalid on this machine.
# Therefore, jump all the way up to the root of the WDAG process and use that window handle as it is local to this machine.
if appModule.appName==WDAG_PROCESS_NAME:
condition=UIAUtils.createUIAMultiPropertyCondition({UIA_ClassNamePropertyId:[u'ApplicationFrameWindow',u'CabinetWClass']})
walker=self.clientObject.createTreeWalker(condition)
else:
# Not WDAG, just walk up to the nearest valid windowHandle
walker=self.windowTreeWalker
try:
new=walker.NormalizeElementBuildCache(UIAElement,self.windowCacheRequest)
except COMError:
return None
try:
window=new.cachedNativeWindowHandle
except COMError:
window=None
if not window:
# This element reports no window handle, so use the nearest ancestor window handle.
try:
new=self.windowTreeWalker.NormalizeElementBuildCache(UIAElement,self.windowCacheRequest)
except COMError:
return None
try:
window=new.cachedNativeWindowHandle
except COMError:
window=None
# Cache for future use to improve performance.
UIAElement._nearestWindowHandle=window
return window
Expand Down