Refactor COM Registration Fixing Tool part 1: make the tool effective on 64-bit Windows and fix more problems#12560
Conversation
See test results for failed build of commit 6c7463fc66 |
See test results for failed build of commit 57d30a95ae |
See test results for failed build of commit 87680deece |
michaelDCurran
left a comment
There was a problem hiding this comment.
Code looks all great to me. However, due to careful testing required and NVDA 2021.1 rc just about to come out, I would like this pr rebased on master for NVDA 2021.2 please.
|
Important fixes, I hope it can be incorporated into the upcoming version. |
|
@michaelDCurran Will do.
There are also two DLLs that are failing to register on some test systems,
and I am working on figuring out why, so this wouldn't have made it to the
release anyway I think.
Initially this looked like it would be more straight forward.
Will rebase on master tomorrow and proceed from there.
|
| if is64bit: | ||
| registerServer(os.path.join(sysWow64,'oleaut32.dll'),wow64=True) | ||
| registerServer(os.path.join(sysWow64,'actxprxy.dll'),wow64=True) | ||
| register64bitServer(os.path.join(sysnative, "oleaut32.dll")) |
There was a problem hiding this comment.
As we are calling the 64 bit version of regsvr32, the dll path we give it must already assume to be 64 bit. Thus, system32 would be the appropriate directory from regsvr32's point of view. In fact, I don't think c:\windows\sysnative is a valid path unless running as a wow64 32 bit process. Same goes for the next line down as well.
|
@michaelDCurran Great catch! I fell prey to the same problem as the original tool had, just in the opposite direction. |
|
@XLTechie Are you still requiring more testing on this? I'm happy to merge this when you are happy. |
|
@lukaszgo1 I believe you have access to Windows 7: can you do any Windows 7 and/or 32-bit testing of this? Particularly interested in whether the original STR can be fixed by the tool with this try-build, and whether any errors appear in the log about anything (but especially registration failures). |
|
@michaelDCurran I have a few tests outstanding that I have requested from people with known COM registration problems, or for whom earlier builds of this fix bugged out. I'd like to hear from at least one or two of them before subjecting this to the wider alpha community. |
Since my only remaining Win 7 machine is my main working one I'm reluctant to do any testing there I'll set up a Vm and try the build from this PR during the weekend. As to 32-bit testing no I don't have any 32-bit Windows install lying around. For what its worth setting up a 32-bit VM should not take long - have you considered testing yourself? |
|
@michaelDCurran I am declaring this good in as far as it goes. You are aware of the work still in progress; another PR will be required when that is done, but it should be a small update given the foundation here. |
|
@michaelDCurran this has been rebased, and now includes your registry key deletion. I have no information suggesting that the other typelib issue described in #9039 is not fixed by this, so I think this PR can close that issue now. |
|
@XLTechie I gave the last build from this PR a try on A Windows 7 X64 VM and everything works as expected. In particular:
|
…64bit Windows (Partial fix of #9039). Problems: - The registerServer function called the 32-bit version of regsvr32.exe, even in 64-bit contexts. - The applyRegistryPatch function called the 32-bit version of regedit, even in 64-bit contexts. - The Win7 32-bit run did not take into account 32-bit only systems (no Program Files (x86) folder). Remediation: - Replaced applyRegistryPatch function with two new functions: apply32bitRegistryPatch and apply64bitRegistryPatch. - Replaced registerServer function with register32bitServer and register64bitServer, to make clear what they do. - The new functions don't check 32/64 bitness; they leave that to the caller and log errors on failure. - Updated to more descriptive error logging. - Adjusted the Windows 7 code to use server registration with proper bitness for each DLL. Path remediations: - Moved the OLEACC_REG_FILE_PATH constant to the top of the file with the rest. - Added sysnative path to the list of path constants at the top of the file. - Now use Sysnative in the path for intentional 64bit calls. - Now use System32 in the path for 32-bit calls on either 32-bit or 64-bit systems. - Now use reg.exe's import option to load .reg files instead of regedit.exe. - Now check whether to use "Program Files" or "Program Files (x86)" on Win7. - Removed now unused sysWow64 path constant. Misc: - Added docstring note about 32 and 64 bit functions needing attention if NVDA goes 64-bit in the future. - Converted path constants to uppercase-with-underscore style, and corrected case on some Windows paths. - Moved comments with discussion links into module docstring, and rearranged. - Used subprocess.STARTUPINFO to prevent console windows from being shown. - In gui/__init__.py: added a recommendation that the user restart the computer, to the completion message.
…ccessible interface key., solving browser problems. Co-authored-by: Michael Curran <michaelDCurran@users.noreply.github.com>
michaelDCurran
left a comment
There was a problem hiding this comment.
Thanks for working on this :)
|
@michaelDCurran Thanks for approving it, and for the pick-up of the final
piece at the end. :)
|
Link to issue number:
Fixes #9039
Summary of the issue:
The COM Registration Fixing Tool seems to have never worked fully on 64bit Windows, as a result of path confusion caused by the use of SysWOW64, and the executable names used.
In addition, modern browsers seem to check a typelib registration that could be damaged by certain uninstallations (e.g. older versions of MathPlayer). We didn't previously do anything about this.
Further background:
In 64 bit Windows,
%WINDIR%\System32contains 64-bit executables. Meanwhile,%WINDIR%\SysWOW64contains 32-bit executables. That seems inverted from what it should be, but there is a good explanation here for why it's like that.When a 32-bit application calls something in
System32, SysWOW64 assumes that it wants the 32-bit version, and redirects the call to the version in theSysWOW64directory.If the 32-bit application really wants the 64-bit version of whatever it's calling, it has to use the virtual directory
%WINDIR%\Sysnative, which SysWOW64 provides.We were calling
regedit.exeandregsvr32.exein contexts where we assumed 32-bit, from either%WINDIR%or%WINDIR%\System32. Because NVDA is 32-bit, that would result in the 32-bit application being called. That's okay.However when the test was made for 64-bit, executables in
%WINDIR%\SysWOW64were being used, which are also 32-bit.At least one of those should be 64-bit for COM reregistrations, but neither are.
In no case should we ever call anything in %WINDIR%\SysWOW64 ourselves, which we currently do.
Description of how this pull request fixes the issue:
Taken from the commit that rewrites
COMRegistrationFixes/__init__.py:Repaired the COM Registration Fixing Tool so it is more effective on 64bit Windows (Partial fix of #9039).
registerServerfunction called the 32-bit version ofregsvr32.exe, even in 64-bit contexts.applyRegistryPatchfunction called the 32-bit version ofregedit, even in 64-bit contexts.Program Files (x86)folder).applyRegistryPatchfunction with two new functions:apply32bitRegistryPatchandapply64bitRegistryPatch.registerServerfunction withregister32bitServerandregister64bitServer, to make clear what they do.OLEACC_REG_FILE_PATHconstant to the top of the file with the rest.Sysnativepath to the list of path constants at the top of the file.Sysnativein the path for intentional 64bit calls.System32in the path for 32-bit calls on either 32-bit or 64-bit systems.reg.exe's import option to load .reg files instead ofregedit.exe.Program Files" or "Program Files (x86)" on Win7.sysWow64path constant.subprocess.STARTUPINFOto prevent console windows from showing during executions.gui/__init__.pyupdate the message shown on tool completion, to recommend a restart.Separately, @michaelDCurran found a registry key that we should delete to restore browser functionality under certain circumstances. That is included as a separate joint commit.
Testing strategy:
Followed the STR in #9039 (comment).
Known issues with pull request:
Windows 7 tests would be valuable, but I can not run them.
My original refactor of this tool is still in progress, but that will now be limited to UX enhancements, since this covers the guts of the tool. These are important updates to the functionality, and imo should be accepted apart from the rest of the refactor.
Change log entries:
Bug fixes
The COM Registration Fixing Tool has been rewritten to solve more problems, and work better on 64bit Windows systems.
Changes for developers:
Code Review Checklist: