Skip to content

Commit 57d30a9

Browse files
authored
Merge e034638 into 98d4b65
2 parents 98d4b65 + e034638 commit 57d30a9

1 file changed

Lines changed: 73 additions & 38 deletions

File tree

Lines changed: 73 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,106 @@
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)")
2122

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

39-
def applyRegistryPatch(fileName,wow64=False):
54+
55+
def apply32bitRegistryPatch(fileName: str) -> None:
56+
"""Applies the registry patch with the given file name, using 32-bit regedit.
57+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
58+
@param fileName: the path to the .reg file
59+
@type fileName: str
4060
"""
41-
Applies the registry patch with the given file name
42-
using regedit.
61+
if not os.path.isfile(fileName):
62+
raise FileNotFoundError(f"Cannot apply 32-bit registry patch: {fileName} not found.")
63+
# On 32-bit systems, regedt32 is in System32. On 64-bit systems, SysWOW64 will redirect to 32-bit version.
64+
regedit = os.path.join(systemRoot, "System32", "regedt32.exe")
65+
try:
66+
subprocess.check_call([regedit, "/s", fileName])
67+
except subprocess.CalledProcessError as e:
68+
log.error(f"Error applying 32-bit registry patch from {fileName} with {regedit}: {e}")
69+
else:
70+
log.debug(f"Applied 32-bit registry patch from {fileName}")
71+
72+
73+
def apply64bitRegistryPatch(fileName: str) -> None:
74+
"""Applies the registry patch with the given file name, using 64-bit regedit.
75+
Note: this function is valid while NVDA remains a 32-bit app. Re-evaluate if we move to 64-bit.
4376
@param fileName: the path to the .reg file
4477
@type fileName: str
4578
"""
4679
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')
80+
raise FileNotFoundError(f"Cannot apply 64-bit registry patch: {fileName} not found.")
81+
# On 64-bit systems, SysWOW64 provides 32-bit apps with a virtual directory to reach 64-bit executables.
82+
# For hard coded historical compatibility, regedt32.exe is still the name of the 64-bit app.
83+
regedit = os.path.join(sysnative, "regedt32.exe")
4984
try:
50-
subprocess.check_call([regedit,'/s',fileName])
85+
subprocess.check_call([regedit, "/s", fileName])
5186
except subprocess.CalledProcessError as e:
52-
log.error("Error applying registry patch: %s with %s, %s"%(fileName,regedit,e))
87+
log.error(f"Error applying 64-bit registry patch from {fileName} with {regedit}: {e}")
5388
else:
54-
log.debug("Applied registry patch: %s with %s"%(fileName,regedit))
89+
log.debug(f"Applied 64-bit registry patch from {fileName}")
5590

5691

57-
OLEACC_REG_FILE_PATH = os.path.join(globalVars.appDir, "COMRegistrationFixes", "oleaccProxy.reg")
5892
def fixCOMRegistrations():
93+
"""Registers most common COM proxies, in case they have accidentally been unregistered or overwritten by
94+
3rd party software installs/uninstalls.
5995
"""
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')
96+
is64bit = os.environ.get("PROCESSOR_ARCHITEW6432","").endswith('64')
6397
winVer = winVersion.getWinVer()
6498
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"))
99+
log.debug("Fixing COM registration for Windows {}.{}, {}".format(OSMajorMinor[0], OSMajorMinor[1], "64 bit" if is64bit else "32 bit"))
66100
# Commands taken from NVDA issue #2807 comment https://github.com/nvaccess/nvda/issues/2807#issuecomment-320149243
101+
# And also the discussions in #9039 https://github.com/nvaccess/nvda/issues/9039
67102
# OLEACC (MSAA) proxies
68-
applyRegistryPatch(OLEACC_REG_FILE_PATH)
103+
apply32bitRegistryPatch(OLEACC_REG_FILE_PATH)
69104
if is64bit:
70-
applyRegistryPatch(OLEACC_REG_FILE_PATH, wow64=True)
105+
apply64bitRegistryPatch(OLEACC_REG_FILE_PATH)
71106
# IDispatch and other common OLE interfaces
72-
registerServer(os.path.join(system32,'oleaut32.dll'))
73-
registerServer(os.path.join(system32,'actxprxy.dll'))
107+
register32bitServer(os.path.join(system32, "oleaut32.dll"))
108+
register32bitServer(os.path.join(system32, "actxprxy.dll"))
74109
if is64bit:
75-
registerServer(os.path.join(sysWow64,'oleaut32.dll'),wow64=True)
76-
registerServer(os.path.join(sysWow64,'actxprxy.dll'),wow64=True)
110+
register64bitServer(os.path.join(sysnative, "oleaut32.dll"))
111+
register64bitServer(os.path.join(sysnative, "actxprxy.dll"))
77112
# IServiceProvider on windows 7 can become unregistered
78-
if OSMajorMinor==(6,1): # Windows 7
79-
registerServer(os.path.join(programFiles,'Internet Explorer','ieproxy.dll'))
113+
if OSMajorMinor == (6, 1): # Windows 7
114+
register32bitServer(os.path.join(programFilesX86, "Internet Explorer", "ieproxy.dll"))
80115
if is64bit:
81-
registerServer(os.path.join(programFilesX86,'Internet Explorer','ieproxy.dll'),wow64=True)
116+
register64bitServer(os.path.join(programFiles, "Internet Explorer", "ieproxy.dll"))

0 commit comments

Comments
 (0)