diff options
author | Tor Lillqvist <tlillqvist@novell.com> | 2010-12-22 15:54:28 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@hemulen.(none)> | 2010-12-22 15:55:22 +0200 |
commit | debf1d0568118f52a23e6c2b2e50c11bd46ed70e (patch) | |
tree | 47173b43a8b39d528bf462ec54b43fdded2e6590 /jvmfwk | |
parent | Remove commented code (diff) | |
download | core-debf1d0568118f52a23e6c2b2e50c11bd46ed70e.tar.gz core-debf1d0568118f52a23e6c2b2e50c11bd46ed70e.zip |
Load msvcr71.dll needed by JVM using explicit path, see fdo#32426
Diffstat (limited to 'jvmfwk')
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx index cff9cdfa05af..3b6296a64b1a 100644 --- a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx @@ -28,6 +28,15 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_jvmfwk.hxx" + +#ifdef WNT +# include <stdio.h> +# include <sys/stat.h> +# include <tools/prewin.h> +# include <windows.h> +# include <tools/postwin.h> +#endif + #if OSL_DEBUG_LEVEL > 0 #include <stdio.h> #endif @@ -430,6 +439,113 @@ javaPluginError jfw_plugin_getJavaInfoByPath( return errcode; } +#if defined(WNT) + +// Load msvcr71.dll using an explicit full path from where it is +// present as bundled with the JRE. In case it is not found where we +// think it should be, do nothing, and just let the implicit loading +// that happens when loading the JVM take care of it. + +static void load_msvcr71(LPCWSTR jvm_dll) +{ + wchar_t msvcr71_dll[MAX_PATH]; + wchar_t *slash; + + if (wcslen(jvm_dll) > MAX_PATH - 15) + return; + + wcscpy(msvcr71_dll, jvm_dll); + + // First check if msvcr71.dll is in the same folder as jvm.dll. It + // normally isn't, at least up to 1.6.0_22, but who knows if it + // might be in the future. + slash = wcsrchr(msvcr71_dll, L'\\'); + + if (!slash) + { + // Huh, weird path to jvm.dll. Oh well. + return; + } + + wcscpy(slash+1, L"msvcr71.dll"); + if (LoadLibraryW(msvcr71_dll)) + return; + + // Then check if msvcr71.dll is in the parent folder of where + // jvm.dll is. That is currently (1.6.0_22) as far as I know the + // normal case. + *slash = 0; + slash = wcsrchr(msvcr71_dll, L'\\'); + + if (!slash) + return; + + wcscpy(slash+1, L"msvcr71.dll"); + LoadLibraryW(msvcr71_dll); +} + +// Check if the jvm DLL imports msvcr71.dll, and in that case try +// loading it explicitly. In case something goes wrong, do nothing, +// and just let the implicit loading try to take care of it. +static void do_msvcr71_magic(rtl_uString *jvm_dll) +{ + FILE *f; + rtl_uString* Module; + oslFileError nError; + struct stat st; + PIMAGE_DOS_HEADER dos_hdr; + IMAGE_NT_HEADERS *nt_hdr; + IMAGE_IMPORT_DESCRIPTOR *imports; + + nError = osl_getSystemPathFromFileURL(jvm_dll, &Module); + + if ( osl_File_E_None != nError ) + rtl_uString_assign(&Module, jvm_dll); + + f = _wfopen(reinterpret_cast<LPCWSTR>(Module->buffer), L"rb"); + + if (fstat(fileno(f), &st) == -1) + { + fclose(f); + return; + } + + dos_hdr = (PIMAGE_DOS_HEADER) malloc(st.st_size); + + if (fread(dos_hdr, st.st_size, 1, f) != 1 || + memcmp(dos_hdr, "MZ", 2) != 0 || + dos_hdr->e_lfanew < 0 || + dos_hdr->e_lfanew > (LONG) (st.st_size - sizeof(IMAGE_NT_HEADERS))) + { + free(dos_hdr); + fclose(f); + return; + } + + fclose(f); + + nt_hdr = (IMAGE_NT_HEADERS *) ((char *)dos_hdr + dos_hdr->e_lfanew); + + imports = (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + nt_hdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + while (imports <= (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + st.st_size - sizeof (IMAGE_IMPORT_DESCRIPTOR)) && + imports->Name != 0 && + imports->Name < (DWORD) st.st_size) + { + // Intentional use of sizeof("msvcr71.dll") here to include the terminating zero byte + if (strnicmp((char *) dos_hdr + imports->Name, "msvcr71.dll", sizeof("msvcr71.dll")) == 0) + { + load_msvcr71(reinterpret_cast<LPCWSTR>(Module->buffer)); + break; + } + imports++; + } + + free(dos_hdr); +} + +#endif + /** starts a Java Virtual Machine. <p> The function shall ensure, that the VM does not abort the process @@ -466,6 +582,9 @@ javaPluginError jfw_plugin_startJavaVirtualMachine( if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) == 0 ) #else +#if defined(WNT) + do_msvcr71_magic(sRuntimeLib.pData); +#endif if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0) #endif { |