diff options
Diffstat (limited to 'jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx')
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx | 128 |
1 files changed, 125 insertions, 3 deletions
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx index b43edf53b3bc..eaaaf3a35aff 100644 --- a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -27,6 +28,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_jvmfwk.hxx" + +#ifdef WNT +# include <stdio.h> +# include <sys/stat.h> +# include <windows.h> +#endif + #if OSL_DEBUG_LEVEL > 0 #include <stdio.h> #endif @@ -58,10 +66,13 @@ #define SUN_MICRO "Sun Microsystems Inc." using namespace osl; -using namespace rtl; using namespace std; using namespace jfw_plugin; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::rtl::OString; + namespace { struct PluginMutex: public ::rtl::Static<osl::Mutex, PluginMutex> {}; @@ -228,7 +239,7 @@ javaPluginError jfw_plugin_getAllJavaInfos( vector<rtl::Reference<VendorBase> > vecVerifiedInfos; typedef vector<rtl::Reference<VendorBase> >::iterator it; - for (it i= vecInfos.begin(); i != vecInfos.end(); i++) + for (it i= vecInfos.begin(); i != vecInfos.end(); ++i) { const rtl::Reference<VendorBase>& cur = *i; @@ -305,7 +316,7 @@ javaPluginError jfw_plugin_getAllJavaInfos( arInfo = (JavaInfo**) rtl_allocateMemory(vecVerifiedInfos.size() * sizeof (JavaInfo*)); int j = 0; typedef vector<rtl::Reference<VendorBase> >::const_iterator cit; - for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ii++, j++) + for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ++ii, ++j) { arInfo[j] = createJavaInfo(*ii); } @@ -429,6 +440,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 @@ -465,6 +583,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 { @@ -674,3 +795,4 @@ javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist) } +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |