[Libreoffice-commits] .: jvmfwk/plugins

Tor Lillqvist tml at kemper.freedesktop.org
Wed Dec 22 05:56:00 PST 2010


 jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx |  119 ++++++++++++++++++++
 1 file changed, 119 insertions(+)

New commits:
commit 504d50d10992aec2b8b3ee45b8d50950762cff24
Author: Tor Lillqvist <tlillqvist at novell.com>
Date:   Wed Dec 22 15:54:28 2010 +0200

    Load msvcr71.dll needed by JVM using explicit path, see fdo#32426

diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx
index 1ff9766..e878422 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
      {


More information about the Libreoffice-commits mailing list