Replies: 1 comment
-
Thanks for your thorough investigation here - sorry we don't have any suggestions at this point |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
When UAC is disabled, using
GetTokenInformation
to check whether the process token has UIAccess will incorrectly return false, even if the process can pass other tests for UIAccess. This makes NVDA disable touch gestures and audio ducking when UAC is disabled, even though the system allows NVDA to do so in this case. Related issues:UIAccess, admin rights, and a high integrity level are different things. If you are an admin and run NVDA with UIAccess, it will have UIAccess and a high integrity level, but not with admin rights, so it can interact with admin windows, but cannot modify system files. And it turns out that the UIAccess flag in the process token and the actual UIAccess rights are also different.
Audio ducking
Audio ducking performs user-mode checks, and a process can pass the test if any of the following is true:
So audio ducking also checks only the process token like our code does, instead of checking the "real" UIAccess rights. This causes the following:
AccSetRunningUtilityState
), regardless of the UIAccess rights.Touch gestures
Touch gestures, or the
RegisterPointerInputTarget
function, also requires UIAccess. However, this function goes into kernel-mode to check the real UIAccess rights.In addition to
RegisterPointerInputTarget
, NVDA's touch handler code also usesAccSetRunningUtilityState
, so it will be affected by the logic used by audio ducking as well.Furthermore, it seems that when UAC is disabled, the system will no longer check the program's digital signature or location. It will be granted UIAccess if its manifest asks for that.
Behavior comparison tables
Following are tables showing the result of different operations when UAC is enabled/disabled, when logged in as an admin/normal user, and when with/without UIAccess.
When UAC is enabled
AccSetRunningUtilityState
RegisterPointerInputTarget
When UAC is disabled
AccSetRunningUtilityState
RegisterPointerInputTarget
Possible ways to detect UIAccess
As shown above, different system components may use different rules when checking for UIAccess rights, even if they just have "requires UIAccess" in their documentation.
As the usual way of checking the process token does not work when UAC is disabled, we might choose some other way as a fallback.
Here are the ways I came up with.
RegisterPointerInputTarget
, but with an invalid input type, for example,PT_POINTER
. This way, the function always fails, and the input target is not actually set. However, we can then check the error code. If it failed withERROR_ACCESS_DENIED
, then it doesn't have UIAccess; if it failed withERROR_INVALID_PARAMETER
, then it has UIAccess.GetWindowBand
to get its band.Which way is better? Or do you have better ways?
cc. @SaschaCowley @seanbudd @michaelDCurran @CyrilleB79 @LeonarddeR
Beta Was this translation helpful? Give feedback.
All reactions