Support for 32 bit sapi4 and sapi5 via a 32 bit synthDriver runtime #19412
Closed
michaelDCurran wants to merge 41 commits into
Closed
Support for 32 bit sapi4 and sapi5 via a 32 bit synthDriver runtime #19412michaelDCurran wants to merge 41 commits into
michaelDCurran wants to merge 41 commits into
Conversation
…ather than 'exposed_' prefix which allows better type checking between proxies and services. Split SynthDriverService.registerNotification into registerSynthIndexReachedNotification and registerSynthDoneSpeakingNotification.
…oved. It will still have read access to the user's files, and write access to the low integrity temp directory.
…rHost32.synthDriver.SynthDriverProxy32. Store actual 32 bit synth drivers in source/synthDrivers32, rather thanb eing built into the runtime. Remove sapi5 32 for now as it is too unstable.
…les / packages for at least sapi4. These need to be explicit as py2exe will no longer scan sapi4.py when building as it is independent of the runtime.
…lled from an elevated process. Use 'removeElevation=True' on SecurePopen to do this.
…er than a strange subset being true. Easier to understand that by default its unrestricted.
… a limited token available). Elevation type of default (which has no linked token at all) is seen when running as system or as local service, so this should be treated as not elevated. Also rewrite how the DACL and SACL are made for the temp window station and desktop, ensuring that even without a restricted token, the SACL is set ensuring that it will work with a low integrity level.
…ng from source. Use maximum sandboxing when launching the host process. SynthDriverProxy32's check method now checks if the runtime is actually available.
… username, domain, password and logonType arguments, allowing for much more general logon scenarios.
…uiredRestrictedSids and include them even if they don't appear in existing groups. This doesn't give more access than the original token allows as the original groups still win. But it is to allow system, when its user SID is removed, to still access desktops via the interactive group etc. Also add an includedSidStrings keyword argument so that more SIDs to restrict can be provided E.g. the unique sandbox SID for this token. SecurePopen: always produce a custom unique sandbox SID rather than relying on the Logon SID, which may not always be available (e.g. running as system). Rather than trying to build our own default DACL from scratch, just add the unique sandbox SID to the token's existing default DACL. All these changes allow running as system with a restricted token that does not include system. Though on some machines COM is still limited it seems.
…ew token's default DACL so that the parent has access to any objects created using the new token. When setting the default DACL and setting the integrity level, ensure not to touch the parent token.
…pen classes to allow configuring of CREATIONFLAGS_CREATE_NO_WINDOW. Set to false by default.
…pen, including logging on by username, create no window, and now the ability to configure if redirection of std handles occurs.
…n dictionaries (one standard and one for secure desktops) at module level so that they can be configured when testing, via the NVDA Pythonconsole.
…command and args to be executed as a Python script using the current Python interpreter as the child process. This makes debugging tests a little easier as then you can guarantee that the child process is the real true Python process and not just another intermediate Py launcher.
…ssing it to the super class.
…cure desktops runs the runtime inside an appContainer running as local service.
… for both synthDrivers and synthDrivers32, ensuring it is available for 32 bit sapi5.
Contributor
|
eSpeak build failed: Also merge the latest beta branch |
Member
Author
|
Closing in favor of a smaller pr that only contains the 32 bit bridge, and none of the security features which will be used by the future ART. These will be added in subsequent releases over 2026. |
5 tasks
SaschaCowley
pushed a commit
that referenced
this pull request
Jan 27, 2026
…19432) Replaces pr #19412 ### Summary of the issue: With the switch to 64 bit, NVDA no longer supports sapi4, or 32 bit specific sapi5 synthesizers. NVDA should somehow continue to support these synthesizers. ### Description of user facing changes: NvDA continues to support sapi4 and 32 bit specific Sapi5 synthesizers. ### Description of developer facing changes: ### Description of development approach: * Compile nvdaHelperLocal for all archetectures, rather than just for NVDA's core archetecture (x64). NVDA's 32 bit synthDriver host runtime needs nvdaHelperLocal for WASAPI. * Move the wasapi function definitions for nvdaHelperLocal.dll into their own 'wasapi' Python module, so that they can be imported separate to NvDAHelper. NVDA's 32 bit synthDriver host runtime uses WASAPI directly. * Compile sonic independently of eSpeak and for all archetectures (not just x64), as it is needed by sapi5 when running in NVDA's 32 bit synthDriver host runtime. The x86 sonic dll will be placed in source/synthDrivers32. * winBindings.kernel32: add definition for GetCurrentProcessId. Used in logging for NVDA's 32 bit synthDriver host runtime. * Add a jobObject module, which contains a Job class which wraps a win32 Job object, which allows automatically killing any process associated with it. This is sued to ensure that any process started for the 32 bit synthDriver host runtime is killed off if NvDA exits. * Add a _bridge package, which provides a client and runtime for the 32 bit synthDriver host. The client is code that runs in NVDA, and the runtime is code that runs in its own 32 bit child process. Communication between NvDA and the child process is via RPYC over the child processs's standard pipe handles. This _bridge package can be later extended with more clients and runtimes as we start to implement a full ART. * Add 32 bit sapi4 and sapi5 synthDrivers which use the synthDriverHost32 runtime. ### Testing strategy: Manually tested running NvDA with both 32 bit sapi4 (Truevoice and MS Mike Mary Sam) and 32 bit sapi5 (Windows built-in David, eSpeak bridge, Mikropuhe). Ran with NvDA launcher, installed normal user, and on secure desktop (UAC and logon screen). ### Known issues with pull request: * This PR only supports sapi4 and 32 bit sapi5 quite specifically. It is not a generalized 32 bit shim for add-ons. To do this, we would need to include the security features from pr #19412 and greatly increase the size of the runtime, and add many more proxies and services. In other words, complete the secure ART project ;). To have something ready for 2026.1, we have decided to limit this to sapi4 and 32 bit sapi5.
Merged
5 tasks
SaschaCowley
pushed a commit
that referenced
this pull request
Feb 23, 2026
…playing directly. (#19577) ### Summary of the issue: the 32 bit sapi synthDrivers added in pr #19432 currently play audio directly. Although this provides good performance and works in most scenarios, it does not allow supporting audio ducking (as the host process does not have permission to duck audio, and if NvDA did ititself, it would inappropriately duck the wrong thing). Also, as we start moving to a secure add-on runtime, 3rd party synthDrivers (at least on secure desktops) will most likely be run in an appContainer, which unfortunately deos not allow the host process to access tha audio device directly. thus, to work around both of these issues, the 32 bit sapi synthDrivers should send the audio to NvDA for playback. ### Description of development approach: Take more code from pr #19412, specifically the WavePlayer service and proxy, the pipe creation code, and raiiUtils. NvDA exposes a WavePlayer service, allowing an external process such as the 32 bit sapi synthDriver processes to send audio. ### Testing strategy: General smoke testing of sapi4 and 32 bit sapi5 synthDrivers. ### Known issues with pull request: * the Mikropuhe sapi5 voices sound a bit scratchy / jittery like there are buffer underruns. I may require some assistance in improving the stability / performance here. Sapi4 truevoice seems to work fine, sapi5 espeak and in-built windows sapi5 voices also seem to be fine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to issue number:
Summary of the issue:
64 bit NVDA can no longer support SAPI4.
Description of user facing changes:
SAPI4 is again availble on 64 bit NVDA.
Description of developer facing changes:
TBD
Description of development approach:
TBD
Testing strategy:
TBD
Known issues with pull request:
None known so far.
Code Review Checklist: