From 8652d50f70d0417628b5a60b77813726019ede20 Mon Sep 17 00:00:00 2001 From: James Teh Date: Thu, 31 Jan 2019 12:18:21 +1000 Subject: [PATCH 1/6] Upgrade SCons to version 3.0.4. This required some tweaks to the sconscripts for ISimpleDOM and MathPlayer. We copy the idl file into the build directory ourselves, but it depends on other files. It seems SCons no longer scans for dependencies in files we copy ourselves. Thus, we must explicitly declare those dependencies. --- include/scons | 2 +- nvdaHelper/ISimpleDOM_sconscript | 9 +++++++-- nvdaHelper/mathPlayer_sconscript | 5 ++++- readme.md | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/scons b/include/scons index 6a72c4de3e9..73b2c02d708 160000 --- a/include/scons +++ b/include/scons @@ -1 +1 @@ -Subproject commit 6a72c4de3e92cae65016578270e6f68e66c4f1e8 +Subproject commit 73b2c02d7088c6d6490fdede8396d88103b00482 diff --git a/nvdaHelper/ISimpleDOM_sconscript b/nvdaHelper/ISimpleDOM_sconscript index 45de6b69cc5..b6ee059060e 100644 --- a/nvdaHelper/ISimpleDOM_sconscript +++ b/nvdaHelper/ISimpleDOM_sconscript @@ -17,8 +17,10 @@ Import('env') env['MIDLCOM']=env['MIDLCOM'][:-6] # Copy some secondary IDL files included by ISimpleDOMNode.idl -env.Command("ISimpleDOMText.idl","#/miscDeps/include/ISimpleDOM/ISimpleDOMText.idl",Copy("$TARGET","$SOURCE")) -env.Command("ISimpleDOMDocument.idl","#/miscDeps/include/ISimpleDOM/ISimpleDOMDocument.idl",Copy("$TARGET","$SOURCE")) +idlDeps = [ + env.Command("ISimpleDOMText.idl","#/miscDeps/include/ISimpleDOM/ISimpleDOMText.idl",Copy("$TARGET","$SOURCE")), + env.Command("ISimpleDOMDocument.idl","#/miscDeps/include/ISimpleDOM/ISimpleDOMDocument.idl",Copy("$TARGET","$SOURCE")), +] # copy ISimpleDOMNode.idl but changing imports of the secondary files to #includes # This is necessary as midl will not build secondary header files. this way the primary header file will contain all secondary header file content idlFile=env.Substfile( @@ -28,6 +30,9 @@ idlFile=env.Substfile( 'import "ISimpleDOM':'#include "ISimpleDOM', } ) +# SCons doesn't scan the file we just created, +# so we must explicitly declare its dependencies. +env.Depends(idlFile, idlDeps) tlbFile,headerFile,iidSourceFile,proxySourceFile,dlldataSourceFile=env.TypeLibrary( source=idlFile, diff --git a/nvdaHelper/mathPlayer_sconscript b/nvdaHelper/mathPlayer_sconscript index 133e20ade14..9d30149daa3 100644 --- a/nvdaHelper/mathPlayer_sconscript +++ b/nvdaHelper/mathPlayer_sconscript @@ -14,8 +14,11 @@ Import('env') -env.Command("MathSpeechEnums.idl","#/miscDeps/include/mathPlayer/MathSpeechEnums.idl",Copy("$TARGET","$SOURCE")) +idlDep = env.Command("MathSpeechEnums.idl","#/miscDeps/include/mathPlayer/MathSpeechEnums.idl",Copy("$TARGET","$SOURCE")) idlFile=env.Command("mathPlayerDLL.idl","#/miscDeps/include/mathPlayer/mathPlayerDLL.idl",Copy("$TARGET","$SOURCE")) +# SCons doesn't scan the file we just created, +# so we must explicitly declare its dependencies. +env.Depends(idlFile, idlDep) tlbFile,headerFile,iidSourceFile,proxySourceFile,dlldataSourceFile=env.TypeLibrary( source=idlFile, diff --git a/readme.md b/readme.md index ec0edbf9c1b..dc05c398cee 100644 --- a/readme.md +++ b/readme.md @@ -72,7 +72,7 @@ For reference, the following dependencies are included in Git submodules: * Adobe FlashAccessibility interface typelib * [txt2tags](http://txt2tags.sourceforge.net/), version 2.5 * [MinHook](https://github.com/RaMMicHaeL/minhook), tagged version 1.2.2 -* [SCons](http://www.scons.org/), version 3.0.0, commit 6a72c4de +* [SCons](http://www.scons.org/), version 3.0.4 * brlapi Python bindings, version 0.5.7 or later, distributed with [BRLTTY for Windows](http://brl.thefreecat.org/brltty/), version 4.2-2 * ALVA BC6 generic dll, version 3.0.4.1 * lilli.dll, version 2.1.0.0 From a417b9863783c7bb6315e5b51bef1a30341ae027 Mon Sep 17 00:00:00 2001 From: James Teh Date: Thu, 31 Jan 2019 12:29:10 +1000 Subject: [PATCH 2/6] Build and install in-process components for ARM64. These are placed in a new libArm64 directory (alongside lib and lib64). MinHook doesn't support ARM64, so disable MinHook and everything that depends on it (notably displayModel). --- nvdaHelper/archBuild_sconscript | 26 +++++--- nvdaHelper/remote/inProcess.cpp | 4 ++ nvdaHelper/remote/injection.cpp | 10 ++- nvdaHelper/remote/rpcSrv.cpp | 4 ++ nvdaHelper/remote/sconscript | 115 +++++++++++++++++--------------- sconstruct | 6 ++ source/setup.py | 1 + 7 files changed, 103 insertions(+), 63 deletions(-) diff --git a/nvdaHelper/archBuild_sconscript b/nvdaHelper/archBuild_sconscript index c9dda300b82..111896e13f3 100644 --- a/nvdaHelper/archBuild_sconscript +++ b/nvdaHelper/archBuild_sconscript @@ -105,15 +105,24 @@ if 'analyze' in debug: env.Append(CXXFLAGS=['/EHsc']) env.Append(CPPPATH=['#/include','#/miscDeps/include',Dir('.').abspath]) +if TARGET_ARCH == "arm64": + subsystem = "/subsystem:windows,6.02" +else: + subsystem = "/subsystem:windows,6.01" env.Append( LINKFLAGS=[ '/incremental:no', '/WX', - '/subsystem:windows,6.01', + subsystem, ] ) env.Append(LINKFLAGS='/release') #We always want a checksum in the header -env.Append(MIDLFLAGS='/x64' if TARGET_ARCH=='x86_64' else '/win32') +if TARGET_ARCH == 'x86_64': + env.Append(MIDLFLAGS='/x64') +elif TARGET_ARCH == 'arm64': + env.Append(MIDLFLAGS='/arm64') +else: + env.Append(MIDLFLAGS='/win32') if not release: env.Append(CCFLAGS=['/Od']) @@ -185,11 +194,12 @@ if signExec: env.AddPostAction(clientLib[0],[signExec]) env.Install(clientInstallDir,clientLib) -minHookLib=env.SConscript('minHook/sconscript') -Export('minHookLib') -if signExec: - env.AddPostAction(minHookLib[0],[signExec]) -env.Install(libInstallDir,minHookLib) +if TARGET_ARCH != 'arm64': + minHookLib=env.SConscript('minHook/sconscript') + Export('minHookLib') + if signExec: + env.AddPostAction(minHookLib[0],[signExec]) + env.Install(libInstallDir,minHookLib) remoteLib=env.SConscript('remote/sconscript') Export('remoteLib') @@ -197,7 +207,7 @@ if signExec: env.AddPostAction(remoteLib[0],[signExec]) env.Install(libInstallDir,remoteLib) -if TARGET_ARCH=='x86_64': +if TARGET_ARCH in ('x86_64', 'arm64'): remoteLoaderProgram=env.SConscript('remoteLoader/sconscript') if signExec: env.AddPostAction(remoteLoaderProgram,[signExec]) diff --git a/nvdaHelper/remote/inProcess.cpp b/nvdaHelper/remote/inProcess.cpp index a618306be43..051976a9537 100755 --- a/nvdaHelper/remote/inProcess.cpp +++ b/nvdaHelper/remote/inProcess.cpp @@ -50,11 +50,15 @@ void inProcess_initialize() { TSF_inProcess_initialize(); IME_inProcess_initialize(); winword_inProcess_initialize(); +#ifndef _M_ARM64 gdiHooks_inProcess_initialize(); +#endif } void inProcess_terminate() { +#ifndef _M_ARM64 gdiHooks_inProcess_terminate(); +#endif IME_inProcess_terminate(); TSF_inProcess_terminate(); winword_inProcess_terminate(); diff --git a/nvdaHelper/remote/injection.cpp b/nvdaHelper/remote/injection.cpp index 54f5defbd94..6394404eb91 100644 --- a/nvdaHelper/remote/injection.cpp +++ b/nvdaHelper/remote/injection.cpp @@ -167,17 +167,21 @@ DWORD WINAPI inprocMgrThreadFunc(LPVOID data) { if(inprocWinEventHookID==0) { LOG_ERROR(L"SetWinEventHook failed"); } +#ifndef _M_ARM64 //Initialize API hooking apiHook_initialize(); //Hook SetWindowsHookExA so that we can juggle hooks around a bit. //Fixes #2411 real_SetWindowsHookExA=apiHook_hookFunction_safe("USER32.dll",SetWindowsHookExA,fake_SetWindowsHookExA); //Fore secure mode NVDA process, hook OpenClipboard to disable usage of the clipboard -if(isSecureModeNVDAProcess) real_OpenClipboard=apiHook_hookFunction_safe("USER32.dll",OpenClipboard,fake_OpenClipboard); + if(isSecureModeNVDAProcess) real_OpenClipboard=apiHook_hookFunction_safe("USER32.dll",OpenClipboard,fake_OpenClipboard); +#endif // #ifndef _M_ARM64 //Initialize in-process subsystems inProcess_initialize(); +#ifndef _M_ARM64 //Enable all registered API hooks apiHook_enableHooks(); +#endif //Initialize our rpc server interfaces and request registration with NVDA rpcSrv_initialize(); //Notify injection_winEventCallback (who started our thread) that we're past initialization @@ -207,8 +211,10 @@ if(isSecureModeNVDAProcess) real_OpenClipboard=apiHook_hookFunction_safe("USER32 #endif //Terminate our RPC server interfaces rpcSrv_terminate(); +#ifndef _M_ARM64 //Unregister and terminate API hooks apiHook_terminate(); +#endif //Terminate all in-process subsystems. inProcess_terminate(); //Unregister any windows hooks registered so far @@ -375,8 +381,10 @@ BOOL WINAPI DllMain(HINSTANCE hModule,DWORD reason,LPVOID lpReserved) { #ifndef NDEBUG Beep(2500,75); #endif +#ifndef _M_ARM64 //Unregister and terminate API hooks apiHook_terminate(); +#endif //Unregister any current windows hooks killRunningWindowsHooks(); //Unregister winEvents for this process diff --git a/nvdaHelper/remote/rpcSrv.cpp b/nvdaHelper/remote/rpcSrv.cpp index 185bebdff3c..7fe728743fb 100755 --- a/nvdaHelper/remote/rpcSrv.cpp +++ b/nvdaHelper/remote/rpcSrv.cpp @@ -20,7 +20,9 @@ This license can be found at: #include "nvdaControllerInternal.h" #include #include "vbufRemote.h" +#ifndef _M_ARM64 #include "displayModelRemote.h" +#endif #include "NvdaInProcUtils.h" #include "nvdaControllerInternal.h" #include "rpcSrv.h" @@ -29,7 +31,9 @@ typedef RPC_STATUS(RPC_ENTRY *RpcServerRegisterIf3_functype)(RPC_IF_HANDLE,UUID RPC_IF_HANDLE availableInterfaces[]={ nvdaInProcUtils_NvdaInProcUtils_v1_0_s_ifspec, +#ifndef _M_ARM64 displayModelRemote_DisplayModel_v1_0_s_ifspec, +#endif VBufRemote_VBuf_v2_0_s_ifspec, }; diff --git a/nvdaHelper/remote/sconscript b/nvdaHelper/remote/sconscript index 4f16334ee3b..7ad3aadfcb2 100644 --- a/nvdaHelper/remote/sconscript +++ b/nvdaHelper/remote/sconscript @@ -60,15 +60,16 @@ vbufRPCHeader,vbufRPCServerSource=env.MSRPCStubs( MSRPCStubs_prefix="VBufRemote_", ) -displayModelRPCHeader,displayModelRPCServerSource=env.MSRPCStubs( - target="./displayModelRemote", - source=[ - "../interfaces/displayModel/displayModel.idl", - "../interfaces/displayModel/displayModel.acf", - ], - MSRPCStubs_noClient=True, - MSRPCStubs_prefix="displayModelRemote_", -) +if env["TARGET_ARCH"] != 'arm64': + displayModelRPCHeader,displayModelRPCServerSource=env.MSRPCStubs( + target="./displayModelRemote", + source=[ + "../interfaces/displayModel/displayModel.idl", + "../interfaces/displayModel/displayModel.acf", + ], + MSRPCStubs_noClient=True, + MSRPCStubs_prefix="displayModelRemote_", + ) nvdaInProcUtilsRPCHeader,nvdaInProcUtilsRPCServerSource=env.MSRPCStubs( target="./nvdaInProcUtils", @@ -82,55 +83,61 @@ nvdaInProcUtilsRPCHeader,nvdaInProcUtilsRPCServerSource=env.MSRPCStubs( ia2utilsObj=env.Object("./ia2utils","../common/ia2utils.cpp") -remoteLib=env.SharedLibrary( - target="nvdaHelperRemote", - source=[ - env['projectResFile'], - "injection.cpp", - "log.cpp", - "inProcess.cpp", - "apiHook.cpp", - "inputLangChange.cpp", - "typedCharacter.cpp", - "ime.cpp", - "tsf.cpp", - "COMProxyRegistration.cpp", - "ia2Support.cpp", - "ia2LiveRegions.cpp", - ia2utilsObj, - env.Object('_ia2_i',ia2RPCStubs[3]), - "rpcSrv.cpp", - "vbufRemote.cpp", - vbufRPCServerSource, - winIPCUtilsObj, - controllerRPCClientSource, - controllerInternalRPCClientSource, - "sysListView32.cpp", - "winword.cpp", - "WinWord/Fields.cpp", - "outlook.cpp", +source = [ + env['projectResFile'], + "injection.cpp", + "log.cpp", + "inProcess.cpp", + "apiHook.cpp", + "inputLangChange.cpp", + "typedCharacter.cpp", + "ime.cpp", + "tsf.cpp", + "COMProxyRegistration.cpp", + "ia2Support.cpp", + "ia2LiveRegions.cpp", + ia2utilsObj, + env.Object('_ia2_i',ia2RPCStubs[3]), + "rpcSrv.cpp", + "vbufRemote.cpp", + vbufRPCServerSource, + winIPCUtilsObj, + controllerRPCClientSource, + controllerInternalRPCClientSource, + "sysListView32.cpp", + "winword.cpp", + "WinWord/Fields.cpp", + "outlook.cpp", + nvdaInProcUtilsRPCServerSource, + "nvdaHelperRemote.def", + vbufBackendLibs, +] +libs = [ + "user32", + "ole32", + "rpcrt4", + "shlwapi", + "oleaut32", + "oleacc", + "usp10", + "imm32", + "advapi32", + "version", + "DbgHelp", +] +# MinHook doesn't support ARM64, which means we can't support displayModel on ARM64. +if env["TARGET_ARCH"] != 'arm64': + source.extend(( "gdiHooks.cpp", "displayModel.cpp", "displayModelRemote.cpp", displayModelRPCServerSource, - nvdaInProcUtilsRPCServerSource, - "nvdaHelperRemote.def", - vbufBackendLibs, - ], - LIBS=[ - "user32", - "gdi32", - "ole32", - "rpcrt4", - "shlwapi", - "oleaut32", - "oleacc", - "usp10", - "imm32", - "advapi32", - "version", - "DbgHelp", - ], + )) + libs.append("gdi32") +remoteLib=env.SharedLibrary( + target="nvdaHelperRemote", + source=source, + LIBS=libs, ) Return('remoteLib') diff --git a/sconstruct b/sconstruct index 38b18eeee7e..82107244f35 100755 --- a/sconstruct +++ b/sconstruct @@ -118,6 +118,8 @@ sourceTypelibDir=sourceDir.Dir('typelibs') Export('sourceTypelibDir') sourceLibDir64=sourceDir.Dir('lib64') Export('sourceLibDir64') +sourceLibDirArm64=sourceDir.Dir('libArm64') +Export('sourceLibDirArm64') buildDir = Dir("build") outFilePrefix = "nvda{type}_{version}".format(type="" if release else "_snapshot", version=version) Export('outFilePrefix') @@ -150,9 +152,11 @@ env['signExec']=signExec archTools=['default','midl','msrpc'] env32=env.Clone(TARGET_ARCH='x86',tools=archTools) env64=env.Clone(TARGET_ARCH='x86_64',tools=archTools) +envArm64=env.Clone(TARGET_ARCH='arm64',tools=archTools) # Hack around odd bug where some tool [after] msvc states that static and shared objects are different env32['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env64['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 +envArm64['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env=env32 @@ -170,6 +174,7 @@ resFile=env.RES(target='build/nvda.res', source=env.Substfile(target='build/nvda.rc', source='nvdaHelper/nvda.rc.subst', SUBST_DICT=projectRCSubstDict)) env32['projectResFile'] = resFile env64['projectResFile'] = resFile +envArm64['projectResFile'] = resFile #Fill sourceDir with anything provided for it by miscDeps env.recursiveCopy(sourceDir,Dir('miscdeps/source')) @@ -179,6 +184,7 @@ env.SConscript('source/comInterfaces_sconscript',exports=['env']) #Process nvdaHelper scons files env32.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env32,'clientInstallDir':clientDir.Dir('x86'),'libInstallDir':sourceLibDir},variant_dir='build/x86') env64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env64,'clientInstallDir':clientDir.Dir('x64'),'libInstallDir':sourceLibDir64},variant_dir='build/x86_64') +envArm64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':envArm64,'clientInstallDir':clientDir.Dir('arm64'),'libInstallDir':sourceLibDirArm64},variant_dir='build/arm64') #Allow all NVDA's gettext po files to be compiled in source/locale for po in env.Glob(sourceDir.path+'/locale/*/lc_messages/*.po'): diff --git a/source/setup.py b/source/setup.py index f71e607e4f8..2e0558a8a36 100755 --- a/source/setup.py +++ b/source/setup.py @@ -221,6 +221,7 @@ def getRecursiveDataFiles(dest,source,excludes=()): ("documentation", ['../copying.txt', '../contributors.txt']), ("lib/%s"%version, glob("lib/*.dll")), ("lib64/%s"%version, glob("lib64/*.dll") + glob("lib64/*.exe")), + ("libArm64/%s"%version, glob("libArm64/*.dll") + glob("libArm64/*.exe")), ("waves", glob("waves/*.wav")), ("images", glob("images/*.ico")), ("louis/tables",glob("louis/tables/*")), From 8d1b1f93b8e2cafa588045753c13d14cb66e92dd Mon Sep 17 00:00:00 2001 From: James Teh Date: Thu, 31 Jan 2019 12:30:49 +1000 Subject: [PATCH 3/6] Start nvdaHelperRemoteLoader appropriately on ARM64. --- source/NVDAHelper.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/NVDAHelper.py b/source/NVDAHelper.py index bc189d7f5d4..830a9cd823f 100755 --- a/source/NVDAHelper.py +++ b/source/NVDAHelper.py @@ -1,6 +1,6 @@ #NVDAHelper.py #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2008-2018 NV Access Limited, Peter Vagner, Davy Kager +#Copyright (C) 2008-2019 NV Access Limited, Peter Vagner, Davy Kager, Mozilla Corporation #This file is covered by the GNU General Public License. #See the file COPYING for more details. @@ -28,7 +28,10 @@ import globalVars versionedLibPath='lib' -versionedLib64Path='lib64' +if os.environ.get('PROCESSOR_ARCHITEW6432') == 'ARM64': + versionedLib64Path = 'libArm64' +else: + versionedLib64Path = 'lib64' if getattr(sys,'frozen',None): # Not running from source. Libraries are in a version-specific directory versionedLibPath=os.path.join(versionedLibPath,versionInfo.version) @@ -496,7 +499,7 @@ def initialize(): log.error("Error installing IA2 support") #Manually start the in-process manager thread for this NVDA main thread now, as a slow system can cause this action to confuse WX _remoteLib.initInprocManagerThreadIfNeeded() - if os.environ.get('PROCESSOR_ARCHITEW6432')=='AMD64': + if os.environ.get('PROCESSOR_ARCHITEW6432') in ('AMD64', 'ARM64'): _remoteLoader64=RemoteLoader64() def terminate(): From e730ce3ec74d5e679d898554b09521c0544cad3f Mon Sep 17 00:00:00 2001 From: James Teh Date: Thu, 31 Jan 2019 12:31:20 +1000 Subject: [PATCH 4/6] Fix AppModule.is64BitProcess for ARM64. Previously, it always returned True, even for 32 bit processes. On ARM64, isWow64Process always returns False. We must instead use IsWow64Process2 where supported. --- source/appModuleHandler.py | 24 ++++++++++++++++++------ source/winKernel.py | 2 ++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/source/appModuleHandler.py b/source/appModuleHandler.py index 1fa98edafc0..52e1afdb7d3 100644 --- a/source/appModuleHandler.py +++ b/source/appModuleHandler.py @@ -1,7 +1,7 @@ # -*- coding: UTF-8 -*- #appModuleHandler.py #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2006-2018 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Patrick Zajda, Joseph Lee, Babbage B.V. +#Copyright (C) 2006-2019 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Patrick Zajda, Joseph Lee, Babbage B.V., Mozilla Corporation #This file is covered by the GNU General Public License. #See the file COPYING for more details. @@ -412,11 +412,23 @@ def _get_is64BitProcess(self): # This is 32 bit Windows. self.is64BitProcess = False return False - res = ctypes.wintypes.BOOL() - if ctypes.windll.kernel32.IsWow64Process(self.processHandle, ctypes.byref(res)) == 0: - self.is64BitProcess = False - return False - self.is64BitProcess = not res + try: + # We need IsWow64Process2 to detect WOW64 on ARM64. + processMachine = ctypes.wintypes.USHORT() + if ctypes.windll.kernel32.IsWow64Process2(self.processHandle, + ctypes.byref(processMachine), None) == 0: + self.is64BitProcess = False + return False + # IMAGE_FILE_MACHINE_UNKNOWN if not a WOW64 process. + self.is64BitProcess = processMachine.value == winKernel.IMAGE_FILE_MACHINE_UNKNOWN + except AttributeError: + # IsWow64Process2 is only supported on Windows 10 version 1511 and later. + # Fall back to IsWow64Process. + res = ctypes.wintypes.BOOL() + if ctypes.windll.kernel32.IsWow64Process(self.processHandle, ctypes.byref(res)) == 0: + self.is64BitProcess = False + return False + self.is64BitProcess = not res return self.is64BitProcess def isGoodUIAWindow(self,hwnd): diff --git a/source/winKernel.py b/source/winKernel.py index 797e29e3a55..2d827078bd5 100644 --- a/source/winKernel.py +++ b/source/winKernel.py @@ -42,6 +42,8 @@ WAIT_OBJECT_0 = 0x00000000L WAIT_TIMEOUT = 0x00000102L WAIT_FAILED = 0xffffffff +# Image file machine constants +IMAGE_FILE_MACHINE_UNKNOWN = 0 def GetStdHandle(handleID): h=kernel32.GetStdHandle(handleID) From 4f5e8b3871f89f677622e8d73530e6d1d2c6850e Mon Sep 17 00:00:00 2001 From: James Teh Date: Thu, 31 Jan 2019 12:54:51 +1000 Subject: [PATCH 5/6] Update readme to list the additional Visual Studio components we now require. --- readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index dc05c398cee..304e6fccd5a 100644 --- a/readme.md +++ b/readme.md @@ -42,10 +42,13 @@ The following dependencies need to be installed on your system: On the Workloads tab, in the Windows group: * Universal Windows Platform Development * Desktop development with C++ - * Then in the Summary list, under Desktop for C++, Optional grouping, ensure the following is selected: + * Then in the Installation details section, under Desktop for C++, Optional grouping, ensure the following are selected: * VC++ 2017 v141 toolset (x86,x64) * Windows 10 SDK (10.0.17134.0) for Desktop C++ x86 and x64 * Visual C++ ATL for x86 and x64 + * In the Installation details section, under Individual components, ensure the following are selected: + * Visual C++ compilers and libraries for ARM64 + * Visual C++ ATL for ARM64 ### Git Submodules From cb67e5827168e3c16ffd3804f327e5df57335e23 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Thu, 31 Jan 2019 15:33:58 +1000 Subject: [PATCH 6/6] Update what's new. --- user_docs/en/changes.t2t | 1 + 1 file changed, 1 insertion(+) diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index 4e80dda1681..641d84bafa2 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -16,6 +16,7 @@ What's New in NVDA - This works in Firefox 66 and later. - This does not work for certain list boxes (HTML select controls) in Chrome. - Added the Afrikaans braille table. (#9186) +- Early support for apps such as Mozilla Firefox on computers with ARM64 (e.g. Qualcom Snapdragon) processors. (#9216) == Changes ==