A crash occurs during install of dotnet35 on a 64-bit prefix as when msi_destroy_assembly_caches is called, the mscoree library is unloaded but the function pointers are not set back to NULL.
The crash occurs within get_clr_version as pGetFileVersion ends up with a value that is neither NULL or valid.
This patch sets the stale function pointers back to NULL.
Signed-off-by: Brendan McGrath brendan@redmandi.com ---
With this patch - a crash still occurs - but this time in PresentationFontCache.exe and the install of dotnet35 continues.
dlls/msi/assembly.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index 7857e8b687f1..f46ff02eeb65 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -36,7 +36,6 @@ static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD ); -static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * ); static HRESULT (WINAPI *pCreateAssemblyNameObject)( IAssemblyName **, LPCWSTR, DWORD, LPVOID ); static HRESULT (WINAPI *pCreateAssemblyEnum)( IAssemblyEnum **, IUnknown *, IAssemblyName *, DWORD, LPVOID ); @@ -52,6 +51,7 @@ static BOOL init_function_pointers( void ) static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0}; static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0}; static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0}; + HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); WCHAR path[MAX_PATH]; DWORD len = GetSystemDirectoryW( path, MAX_PATH );
@@ -121,6 +121,9 @@ void msi_destroy_assembly_caches( MSIPACKAGE *package ) pCreateAssemblyCacheNet11 = NULL; pCreateAssemblyCacheNet20 = NULL; pCreateAssemblyCacheNet40 = NULL; + pGetFileVersion = NULL; + pCreateAssemblyNameObject = NULL; + pCreateAssemblyEnum = NULL; FreeLibrary( hfusion10 ); FreeLibrary( hfusion11 ); FreeLibrary( hfusion20 );
The current behaviour causes a crash during install of dotnet35 on a 64-bit prefix. This is because the 32-bit install looks for mscoree.dll in the 'System32' dir which is a 64-bit binary thus no valid mscoree.dll can be loaded.
The crash actually occurs within get_clr_version as pGetFileVersion ends up with a value that is neither NULL or valid (fixed in patch 1 of this series).
This patch allows the syswow64 version of mscoree.dll to be found and used.
Signed-off-by: Brendan McGrath brendan@redmandi.com ---
With this patch no crash occurs during a dotnet35 install. However, I'm not sure if this is the correct approach as the use of 'System32' seems quite intentional.
dlls/msi/assembly.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index f46ff02eeb65..fddca209ad70 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -45,15 +45,13 @@ static HMODULE hfusion10, hfusion11, hfusion20, hfusion40, hmscoree, hsxs; static BOOL init_function_pointers( void ) { static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; - static const WCHAR szMscoree[] = {'\','m','s','c','o','r','e','e','.','d','l','l',0}; + static const WCHAR szMscoree[] = {'m','s','c','o','r','e','e','.','d','l','l',0}; static const WCHAR szSxs[] = {'s','x','s','.','d','l','l',0}; static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0}; static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0}; static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0}; static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0}; HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); - WCHAR path[MAX_PATH]; - DWORD len = GetSystemDirectoryW( path, MAX_PATH );
if (!hsxs && !(hsxs = LoadLibraryW( szSxs ))) return FALSE; if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) @@ -62,8 +60,7 @@ static BOOL init_function_pointers( void ) hsxs = NULL; return FALSE; } - strcpyW( path + len, szMscoree ); - if (hmscoree || !(hmscoree = LoadLibraryW( path ))) return TRUE; + if (hmscoree || !(hmscoree = LoadLibraryW( szMscoree ))) return TRUE; pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */ if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) {
On Mon, 2018-11-26 at 20:23 +1100, Brendan McGrath wrote:
The current behaviour causes a crash during install of dotnet35 on a 64-bit prefix. This is because the 32-bit install looks for mscoree.dll in the 'System32' dir which is a 64-bit binary thus no valid mscoree.dll can be loaded.
The crash actually occurs within get_clr_version as pGetFileVersion ends up with a value that is neither NULL or valid (fixed in patch 1 of this series).
This patch allows the syswow64 version of mscoree.dll to be found and used.
Signed-off-by: Brendan McGrath brendan@redmandi.com
With this patch no crash occurs during a dotnet35 install. However, I'm not sure if this is the correct approach as the use of 'System32' seems quite intentional.
It is. We shouldn't load mscoree from the current directory. Is there a bug report for this issue?