Skip to content

Commit 87680de

Browse files
authored
Merge bc89a75 into 98d4b65
2 parents 98d4b65 + bc89a75 commit 87680de

1 file changed

Lines changed: 77 additions & 38 deletions

File tree

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# A part of NonVisual Desktop Access (NVDA)
2-
# Copyright (C) 2018-2020 NV Access Limited
2+
# Copyright (C) 2018-2021 NV Access Limited
33
# This file is covered by the GNU General Public License.
44
# See the file COPYING for more details.
55

@@ -11,71 +11,110 @@
1111
import globalVars
1212
from logHandler import log
1313

14+
OLEACC_REG_FILE_PATH = os.path.join(globalVars.appDir, "COMRegistrationFixes", "oleaccProxy.reg")
1415
# Particular 64 bit / 32 bit system paths
15-
systemRoot=os.path.expandvars('%SYSTEMROOT%')
16-
system32=os.path.join(systemRoot,'system32')
17-
sysWow64=os.path.join(systemRoot,'syswow64')
18-
systemDrive=os.path.expandvars('%SYSTEMDRIVE%\\')
19-
programFiles=os.path.join(systemDrive,'program files')
20-
programFilesX86=os.path.join(systemDrive,'program files (x86)')
16+
systemRoot = os.path.expandvars("%SYSTEMROOT%")
17+
system32 = os.path.join(systemRoot, "System32")
18+
sysnative = os.path.join(systemRoot, "Sysnative") # Virtual folder for reaching 64-bit exes from 32-bit apps
19+
systemDrive = os.path.expandvars("%SYSTEMDRIVE%\\")
20+
programFiles = os.path.join(systemDrive, "program files")
21+
programFilesX86 = os.path.join(systemDrive, "program files (x86)")
22+
2123

22-
def registerServer(fileName,wow64=False):
24+
def register32bitServer(fileName: str) -> None:
25+
"""Registers the COM proxy dll with the given file name, using the 32-bit version of regsvr32.
26+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
27+
@param fileName: the path to the dll
28+
@type fileName: str
2329
"""
24-
Registers the COM proxy dll with the given file name
25-
Using regsvr32.
30+
# Points to the 32-bit version, on Windows 32-bit or 64-bit.
31+
regsvr32 = os.path.join(system32, "regsvr32.exe")
32+
try:
33+
subprocess.check_call([regsvr32, "/s", fileName])
34+
except subprocess.CalledProcessError as e:
35+
log.error(f"Error registering {fileName} in a 32-bit context: {e}")
36+
else:
37+
log.debug(f"Registered {fileName} in a 32-bit context.")
38+
39+
40+
def register64bitServer(fileName: str) -> None:
41+
"""Registers the COM proxy dll with the given file name, using the 64-bit version of regsvr64.
42+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
2643
@param fileName: the path to the dll
2744
@type fileName: str
28-
@param wow64: If true then the 32 bit (wow64) version of regsvr32 will be used.
29-
@type wow64: bool
3045
"""
31-
regsvr32=os.path.join(sysWow64 if wow64 else system32,'regsvr32.exe')
46+
# SysWOW64 provides a virtual directory to allow 32-bit programs to reach 64-bit executables.
47+
regsvr32 = os.path.join(sysnative, "regsvr32.exe")
3248
try:
33-
subprocess.check_call([regsvr32,'/s',fileName])
49+
subprocess.check_call([regsvr32, "/s", fileName])
3450
except subprocess.CalledProcessError as e:
35-
log.error("Error registering %s, %s"%(fileName,e))
51+
log.error(f"Error registering {fileName} in a 64-bit context: {e}")
3652
else:
37-
log.debug("Registered %s"%fileName)
53+
log.debug(f"Registered {fileName} in a 64-bit context.")
54+
3855

39-
def applyRegistryPatch(fileName,wow64=False):
56+
def apply32bitRegistryPatch(fileName: str) -> None:
57+
"""Applies the registry patch with the given file name, using 32-bit regedit.
58+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
59+
@param fileName: the path to the .reg file
60+
@type fileName: str
4061
"""
41-
Applies the registry patch with the given file name
42-
using regedit.
62+
if not os.path.isfile(fileName):
63+
raise FileNotFoundError(f"Cannot apply 32-bit registry patch: {fileName} not found.")
64+
# On 32-bit systems, regedt32 is in System32. On 64-bit systems, SysWOW64 will redirect to 32-bit version.
65+
regedit = os.path.join(systemRoot, "System32", "regedt32.exe")
66+
try:
67+
subprocess.check_call([regedit, "/s", fileName])
68+
except subprocess.CalledProcessError as e:
69+
log.error(f"Error applying 32-bit registry patch from {fileName} with {regedit}: {e}")
70+
else:
71+
log.debug(f"Applied 32-bit registry patch from {fileName}")
72+
73+
74+
def apply64bitRegistryPatch(fileName: str) -> None:
75+
"""Applies the registry patch with the given file name, using 64-bit regedit.
76+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
4377
@param fileName: the path to the .reg file
4478
@type fileName: str
4579
"""
4680
if not os.path.isfile(fileName):
47-
raise FileNotFoundError(f"Cannot apply registry patch, {fileName} not found.")
48-
regedit=os.path.join(sysWow64 if wow64 else systemRoot,'regedit.exe')
81+
raise FileNotFoundError(f"Cannot apply 64-bit registry patch: {fileName} not found.")
82+
# On 64-bit systems, SysWOW64 provides 32-bit apps with a virtual directory to reach 64-bit executables.
83+
# For hard coded historical compatibility, regedt32.exe is still the name of the 64-bit app.
84+
regedit = os.path.join(sysnative, "regedt32.exe")
4985
try:
50-
subprocess.check_call([regedit,'/s',fileName])
86+
subprocess.check_call([regedit, "/s", fileName])
5187
except subprocess.CalledProcessError as e:
52-
log.error("Error applying registry patch: %s with %s, %s"%(fileName,regedit,e))
88+
log.error(f"Error applying 64-bit registry patch from {fileName} with {regedit}: {e}")
5389
else:
54-
log.debug("Applied registry patch: %s with %s"%(fileName,regedit))
90+
log.debug(f"Applied 64-bit registry patch from {fileName}")
5591

5692

57-
OLEACC_REG_FILE_PATH = os.path.join(globalVars.appDir, "COMRegistrationFixes", "oleaccProxy.reg")
5893
def fixCOMRegistrations():
94+
"""Registers most common COM proxies, in case they have accidentally been unregistered or overwritten by
95+
3rd party software installs/uninstalls.
5996
"""
60-
Registers most common COM proxies, in case they had accidentally been unregistered or overwritten by 3rd party software installs/uninstalls.
61-
"""
62-
is64bit=os.environ.get("PROCESSOR_ARCHITEW6432","").endswith('64')
97+
is64bit = os.environ.get("PROCESSOR_ARCHITEW6432", "").endswith("64")
6398
winVer = winVersion.getWinVer()
6499
OSMajorMinor = (winVer.major, winVer.minor)
65-
log.debug("Fixing COM registration for Windows %s.%s, %s"%(OSMajorMinor[0],OSMajorMinor[1],"64 bit" if is64bit else "32 bit"))
100+
log.debug(
101+
f"Fixing COM registration for Windows {OSMajorMinor[0]}.{OSMajorMinor[1]}, "
102+
"{} bit.".format("64" if is64bit else "32")
103+
)
66104
# Commands taken from NVDA issue #2807 comment https://github.com/nvaccess/nvda/issues/2807#issuecomment-320149243
105+
# And also the discussions in #9039 https://github.com/nvaccess/nvda/issues/9039
67106
# OLEACC (MSAA) proxies
68-
applyRegistryPatch(OLEACC_REG_FILE_PATH)
107+
apply32bitRegistryPatch(OLEACC_REG_FILE_PATH)
69108
if is64bit:
70-
applyRegistryPatch(OLEACC_REG_FILE_PATH, wow64=True)
109+
apply64bitRegistryPatch(OLEACC_REG_FILE_PATH)
71110
# IDispatch and other common OLE interfaces
72-
registerServer(os.path.join(system32,'oleaut32.dll'))
73-
registerServer(os.path.join(system32,'actxprxy.dll'))
111+
register32bitServer(os.path.join(system32, "oleaut32.dll"))
112+
register32bitServer(os.path.join(system32, "actxprxy.dll"))
74113
if is64bit:
75-
registerServer(os.path.join(sysWow64,'oleaut32.dll'),wow64=True)
76-
registerServer(os.path.join(sysWow64,'actxprxy.dll'),wow64=True)
114+
register64bitServer(os.path.join(sysnative, "oleaut32.dll"))
115+
register64bitServer(os.path.join(sysnative, "actxprxy.dll"))
77116
# IServiceProvider on windows 7 can become unregistered
78-
if OSMajorMinor==(6,1): # Windows 7
79-
registerServer(os.path.join(programFiles,'Internet Explorer','ieproxy.dll'))
117+
if OSMajorMinor == (6, 1): # Windows 7
118+
register32bitServer(os.path.join(programFilesX86, "Internet Explorer", "ieproxy.dll"))
80119
if is64bit:
81-
registerServer(os.path.join(programFilesX86,'Internet Explorer','ieproxy.dll'),wow64=True)
120+
register64bitServer(os.path.join(programFiles, "Internet Explorer", "ieproxy.dll"))

0 commit comments

Comments
 (0)