summaryrefslogtreecommitdiff
path: root/jvmfwk/plugins
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@novell.com>2010-12-22 15:54:28 +0200
committerTor Lillqvist <tml@hemulen.(none)>2010-12-22 15:55:22 +0200
commitdebf1d0568118f52a23e6c2b2e50c11bd46ed70e (patch)
tree47173b43a8b39d528bf462ec54b43fdded2e6590 /jvmfwk/plugins
parent6505a6eda9dab7baeb45540fee9b0b9d1930218c (diff)
Load msvcr71.dll needed by JVM using explicit path, see fdo#32426
Diffstat (limited to 'jvmfwk/plugins')
-rw-r--r--jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx119
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
{