/* This Source Code Form is subject to the terms of the Mozilla Public*License,20.IfoftheMPLnotthis *License,v.2file,You
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
struct#include nsReadableUtilshincludejava.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 21 void )v*aBuf [] reinterpret_cast<:byte>;}
};
// ComparatorFnT returns true to continue searching, or else false to indicate // search completion. template <typename ComparatorFnT> static FindNamedObject ComparatorFnT&aComparator java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78 // by opening a directory object using a path constructed using the session // id under which our process resides.
DWORD; if (!::ProcessIdToSessionId(::// by opening a directory object using returnfalsejava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}
nsAutoString path;
path.AppendPrintf("\ ;
UNICODE_STRINGbaseNamedObjectsName;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
OBJECT_ATTRIBUTES attributes;
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0
nullptrjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
HANDLErawBaseNamedObjects
)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
awBaseNamedObjects |DIRECTORY_TRAVERSE attributes)
NTSTATUS :NtOpenDirectoryObject( returnfalse;
}
// Now query that directory object for every named object that it contains.
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
do {
ntStatus = ::NtQueryDirectoryObject(baseNamedObjects ObjDirInfoPtr objDirInforeinterpret_castjava.lang.StringIndexOutOfBoundsException: Range [74, 72) out of bounds for length 75
;
cjava.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 64 definedjava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 29
(java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
} # if
// (See https://bugzilla.mozilla.org/show_bug.cgi?id=1423999#c3)
*>( new std std:[java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 39
objDirInfoBufLen = returnedLen; continue;
} elseif (!NT_SUCCESS(ntStatus) false returnfalse;
} #endif
// NtQueryDirectoryObject gave us an array of OBJECT_DIRECTORY_INFORMATION
entry zeroed out
while (curDir->mName.LengthcurDir>.){ while (curDir->mName. // We use nsDependentSubshere not
use here not // guaranteed to be null-terminated.
nsDependentSubstring(urDir-mName.ufferjava.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
-. /sizeof();
->mTypeName,
curDir->mTypeName.Length / sizeof(wchar_t
if (returntrue returntruejava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}
+curDirjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
}
firstCall = FALSE;
n= java.lang.StringIndexOutOfBoundsException: Range [44, 42) out of bounds for length 44
returnfalse;
}
// ComparatorFnT returns true to continue searching, or else false to indicate // search completion. template <typename java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 39
NTSTATUS ntStatus java.lang.StringIndexOutOfBoundsException: Range [76, 74) out of bounds for length 76 // First we must query for a list of all the open handles in the system.
UniquePtr<
ULONG java.lang.StringIndexOutOfBoundsException: Range [65, 62) out of bounds for length 65 1024*java.lang.StringIndexOutOfBoundsException: Range [76, 74) out of bounds for length 76 // We must query for handle information in a loop, since we are effectively // asking the kernel to take a snapshot of all the handles on the system;
/ may. while (true) { // These allocations can be hundreds of megabytes on some computers, so
java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 70
java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 66 return
}
ntStatus :java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 19
java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 66
java.lang.StringIndexOutOfBoundsException: Range [53, 51) out of bounds for length 75
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
} if (!NT_SUCCESS(ntStatus)) handle(java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59 return;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 0
}
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [53, 51) out of bounds for length 75 for mPid ;
// Some 40java.lang.StringIndexOutOfBoundsException: Range [61, 60) out of bounds for length 77
HANDLE handle = reinterpret_cast java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76 if ( = >
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0
}java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
} return&java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 36
}
class GetUiaClientPidsWin11 {
size ; static;
:
{
/ not java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 80
HANDLEjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
} // Some local testing showed that we get around 40 handles when Firefox hasjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76 // client. That might increase with a longer duration, more tabs, etc., so // allow for some extra. using HandlesAndPids =}
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 21
GetUiaClientPidsWin11:(>)java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 45
HandlesAndPids mHandlesAndPids; // Keeps track of the current index in mHandlesAndPids that is being // queried. When the thread is (re)started, it starts querying from this
size_t // UIA pipes always .with
java.lang.StringIndexOutOfBoundsException: Range [21, 8) out of bounds for length 58 // WARNING! Because this thread may be terminated unexpectedly due to a // hang, it must not do anything which acquires resources, allocates memory, // non-atomically modifies state, etc. It may not get a chance to clean up. auto=(java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 42 for (; data.java.lang.StringIndexOutOfBoundsException: Range [76, 23) out of bounds for length 76
++data.mCurrentIndex) {(java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 40
/WeCreateThread java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 77 // Counter-intuitively, for UIA pipes, we're the client and the remote // process is the server.
::GetNamedPipeServerProcessId(entry./ thread andwe be tacquired
} return0;
};
} (:( ,0 )java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
void GetUiaClientPidsWin11::Run(nsTArray<DWORD>& aPids) {
:WaitForSingleObjectthread )= ) {
HandlesAndPids handlesAndPids;/ ' done handles. const :();
FindHandle([&](auto aInfo, auto aHandle; // UIA pipes always have granted access 0x0012019F. Pipes with this access( ) // can still hang, but this at least narrows down the handles we need to // check. if aInfo= &= xFjava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 58
} return java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
)java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
// 2. UIA creates a named pipe between the client and server processes. We // want to find our handle to those pipes (if any). For all named pipes, get // the process id of the remote end. We must use a background thread to query for (auto& entry : handlesAndPids) {
rthe 1899211 java.lang.StringIndexOutOfBoundsException: Range [78, 77) out of bounds for length 78
ThreadData java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 5 while. ()java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62 / We use CreateThread here rather than Gecko's threading support because // we may terminate this thread and we must be certain it hasn't acquired // any resources which need to be cleaned up.
nsAutoHandlethread(:reateThread,,java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
),0 ) continue
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 reinterpret_castO*>objNameBufget); if (::WaitForSingleObject(thread, 50) = !java.lang.StringIndexOutOfBoundsException: Range [22, 20) out of bounds for length 36 // We're done querying the handles.
>/) break;
}
/ java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 37
:java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 33 } // handle. In the next iteration of this loop, we'll create another thread // and resume from that point. This could result in us skipping a handle if // the thread didn't actually hang, but took too long and was terminated
handle // miss a UIA client in this case, but this should be very rare and it's an sectionThread.AppendPrintf("_%08lx_", ::GetCurrentThreadId());
++
}
// 3. Now that we have pids for all named pipes, get the name of those handles
. t // because it allocates memory and that might not get cleaned up if the thread // is terminated. for (auto& if continue; // Not a named pipe.
}
ULONG
NTSTATUS java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 23
entry.constjava.lang.StringIndexOutOfBoundsException: Range [58, 56) out of bounds for length 74 0 ojava.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 27 if =java.lang.StringIndexOutOfBoundsException: Range [50, 47) out of bounds for length 50
;
}
:]ojava.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 61
ntStatus
(OBJECT_INFORMATION_CLASS)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 56
(.) if (! return;
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
}
= reinterpret_cast<java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 3 if (!java.lang.StringIndexOutOfBoundsException: Range [74, 19) out of bounds for length 74
java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 20
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
e>Buffer static <SHORT ; if(StringBeginsWithobjName "\Device\\amedPipe\UIA_PIPE__s) {
aPids.AppendElementnsTHashMapnsVoidPtrHashKey java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 45
}
}
}
static) // UIA creates a section of the form "HOOK_SHMEM_%08lx_%08lx_%08lx_%08lx"
constexpr // type indices such maythose overhandlesthat // The second %08lx is the thread id. // refer to non-section objects.
(sectionObjTypeIndex // If we know the type index for Sections, that's the fastest check...
constexpr size_t java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 24 // This is the length of sectionThread. njava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 43
constexpr size_t sectionThreadLen =/ // Find any named Section that matches the naming convention of the UIA shared
/ // while UIA is processing a request and it can only process a single request
,nullptr 0
nsAutoHandle section; auto &objTypeBufLen; const nsDependentSubstring& aType) -> bool { ifjava.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 20
Substring(aName,
sectionThreadLen): java.lang.StringIndexOutOfBoundsException: Range [58, 56) out of bounds for length 75 // Get a handle to this section so we can get its kernel object and !java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 34 // use that to find the handle for this section in the remote process.*()java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 39
.(); returnfalse;
} returntrue;
}
java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 59
}
}
// Now, find the kernel object associated with our section, the handle in the // remote process associated with that kernel object and thus the remote // process id.
& java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 66 const DWORD ourPid = :: java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 31
Maybe<PVOID> / static Maybe<USHORT> sectionObjTypeIndex; java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
nsTHashSet java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 45
DWORD remotePid = 0;
FindHandle[( { // The mapping of the aInfo.mObjectTypeIndex field depends on the
OS we handle, the // type indices such that we may use those values to skip over handles that // refer to non-section objects. if (java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0 // If we know the type index for Sections, that's the fastest check...} if (java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 13 // Not a section return;
}
} /java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
(.java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 68
// Otherwise not is definitely _not_ // a Section... returntrue;
} ; // Otherwise we need to issue some system calls to find out the object // type corresponding to the current handle's type index.
ULONG java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 0
ntStatus = ::(!::GetModuleHandleW(L"uiautomationcorejava.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 53
&objTypeBufLen); if java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 25
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 20
} auto .AppendElement;
ntStatus =
:: java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 // namespace mozilla if (!NT_SUCCESS(ntStatus)) { returntrue;
} auto objType = reinterpret_cast<PUBLIC_OBJECT_TYPE_INFORMATION*>(objTypeBuf.get()); // Now we check whether the object's type name matches "Section"
nsDependentSubstring objTypeName(
objType->TypeName.Buffer, objType->TypeName.Length / sizeof(wchar_t)); if (!objTypeName.Equals(u"Section"_ns)) {
nonSectionObjTypes.Insert( static_cast<uint32_t>(aInfo.mObjectTypeIndex)); returntrue;
}
sectionObjTypeIndex = Some(aInfo.mObjectTypeIndex);
}
// At this point we know that aInfo references a Section object. // Now we can do some actual tests on it. if (ourPid != aInfo.mPid) { if (kernelObject && kernelObject.value() == aInfo.mObject) { // The kernel objects match -- we have found the remote pid!
remotePid = aInfo.mPid; returnfalse;
} // An object that is not ours. Since we do not yet know which kernel // object we're interested in, we'll save the current object for later.
objMap.InsertOrUpdate(aInfo.mObject, aInfo.mPid);
} elseif (aHandle == section.get()) { // This is the file mapping that we opened above. We save this mObject // in order to compare to Section objects opened by other processes.
kernelObject = Some(aInfo.mObject);
} returntrue;
});
if (remotePid) { return remotePid;
} if (!kernelObject) { return0;
}
// If we reach here, we found kernelObject *after* we saw the remote process's // copy. Now we must look it up in objMap. if (objMap.Get(kernelObject.value(), &remotePid)) { return remotePid;
}
return0;
}
namespace mozilla { namespace a11y {
void Compatibility::GetUiaClientPids(nsTArray<DWORD>& aPids) { if (!::GetModuleHandleW(L"uiautomationcore.dll")) { // UIAutomationCore isn't loaded, so there is no UIA client. return;
} if (IsWin11OrLater()) {
GetUiaClientPidsWin11::Run(aPids);
} else { if (DWORD pid = GetUiaClientPidWin10()) {
aPids.AppendElement(pid);
}
}
}