6797688: Umbrella: Merge all JDK 6u4 - 6u12 deployment code into JDK7
6845973: Update JDK7 with deployment changes in 6u13, 6u14
4802695: Support 64-bit Java Plug-in and Java webstart on Windows/Linux on AMD64
6825019: DownloadManager should not be loaded and referenced for full JRE
6738770: REGRESSION:JSException throws when use LiveConnect javascript facility
6772884: plugin2 : java.lang.OutOfMemoryError or crash
6707535: Crossing domain hole affecting multiple sites/domains using plug-in
6728071: Non-verification of Update files may allow unintended updates
6704154: Code loaded from local filesystem should not get access to localhost
6727081: Web Start security restrictions bypass using special extension jnlp
6727079: Java Web Start Socket() restriction bypass
6727071: Cache location/user name information disclosure in SingleInstanceImpl.
6716217: AppletClassLoader adds permissions based on codebase regardless of CS
6694892: Java Webstart inclusion via system properties override [CVE-2008-2086]
6704074: localhost socket access due to cache location exposed
6703909: Java webstart arbitrary file creation using nativelib
6665315: browser crashes when deployment.properties has more slashes ( / )
6660121: Encoding values in JNLP files can cause buffer overflow
6606110: URLConnection.setProxiedHost for resources that are loaded via proxy
6581221: SSV(VISTA): Redirection FAILS to work if user does a downgrade install
6609756: Buffer Overflow in Java ActiveX component
6608712: Bypassing the same origin policy in Java with crafted names
6534630: "gnumake clobber" doesn't
6849953: JDK7 - replacement of bufferoverflowU.lib on amd64 breaks build
6849029: Need some JDK7 merge clean-up after comments on the webrev
6847582: Build problem on JDK7 with isSecureProperty in merge
6827935: JDK 7 deployment merging - problem in Compiler-msvm.gmk
6823215: latest merge fixes from 6u12 -> JDK7
6816153: further mergers for JDK7 deployment integration
6807074: Fix Java Kernel and JQS in initial JDK7 builds
Summary: Initial changeset for implementing 6uX Deployment Features into JDK7
Reviewed-by: dgu, billyh
diff --git a/src/windows/bin/java_md.c b/src/windows/bin/java_md.c
index c468258..df5e698 100644
--- a/src/windows/bin/java_md.c
+++ b/src/windows/bin/java_md.c
@@ -49,6 +49,7 @@
 static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
                            char *jvmpath, jint jvmpathsize);
 static jboolean GetJREPath(char *path, jint pathsize);
+static void EnsureJreInstallation(const char *jrepath);
 
 static jboolean _isjavaw = JNI_FALSE;
 
@@ -108,6 +109,9 @@
         exit(1);
     }
 
+    /* Do this before we read jvm.cfg */
+    EnsureJreInstallation(jrepath);
+
     /* Find out where the JRE is that we will be using. */
     if (!GetJREPath(jrepath, so_jrepath)) {
         JLI_ReportErrorMessage(JRE_ERROR1);
@@ -130,6 +134,103 @@
 
 }
 
+
+static jboolean
+LoadMSVCRT()
+{
+    // Only do this once
+    static int loaded = 0;
+    char crtpath[MAXPATHLEN];
+
+    if (!loaded) {
+        /*
+         * The Microsoft C Runtime Library needs to be loaded first.  A copy is
+         * assumed to be present in the "JRE path" directory.  If it is not found
+         * there (or "JRE path" fails to resolve), skip the explicit load and let
+         * nature take its course, which is likely to be a failure to execute.
+         */
+#ifdef _MSC_VER
+#if _MSC_VER < 1400
+#define CRT_DLL "msvcr71.dll"
+#endif
+#ifdef CRT_DLL
+        if (GetJREPath(crtpath, MAXPATHLEN)) {
+            (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL);   /* Add crt dll */
+            JLI_TraceLauncher("CRT path is %s\n", crtpath);
+            if (_access(crtpath, 0) == 0) {
+                if (LoadLibrary(crtpath) == 0) {
+                    JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
+                    return JNI_FALSE;
+                }
+            }
+        }
+#endif /* CRT_DLL */
+#endif /* _MSC_VER */
+        loaded = 1;
+    }
+    return JNI_TRUE;
+}
+
+/*
+ * The preJVMStart is a function in the jkernel.dll, which
+ * performs the final step of synthesizing back the decomposed
+ * modules  (partial install) to the full JRE. Any tool which
+ * uses the  JRE must peform this step to ensure the complete synthesis.
+ * The EnsureJreInstallation function calls preJVMStart based on
+ * the conditions outlined below, noting that the operation
+ * will fail silently if any of conditions are not met.
+ * NOTE: this call must be made before jvm.dll is loaded, or jvm.cfg
+ * is read, since jvm.cfg will be modified by the preJVMStart.
+ * 1. Are we on a supported platform.
+ * 2. Find the location of the JRE or the Kernel JRE.
+ * 3. check existence of JREHOME/lib/bundles
+ * 4. check jkernel.dll and invoke the entry-point
+ */
+typedef VOID (WINAPI *PREJVMSTART)();
+
+static void
+EnsureJreInstallation(const char* jrepath)
+{
+    HINSTANCE handle;
+    char tmpbuf[MAXPATHLEN];
+    PREJVMSTART PreJVMStart;
+    struct stat s;
+
+    /* 32 bit windows only please */
+    if (strcmp(GetArch(), "i386") != 0 ) {
+        return;
+    }
+    /* Does our bundle directory exist ? */
+    strcpy(tmpbuf, jrepath);
+    strcat(tmpbuf, "\\lib\\bundles");
+    if (stat(tmpbuf, &s) != 0) {
+        return;
+    }
+    /* Does our jkernel dll exist ? */
+    strcpy(tmpbuf, jrepath);
+    strcat(tmpbuf, "\\bin\\jkernel.dll");
+    if (stat(tmpbuf, &s) != 0) {
+        return;
+    }
+    /* The Microsoft C Runtime Library needs to be loaded first. */
+    if (!LoadMSVCRT()) {
+        return;
+    }
+    /* Load the jkernel.dll */
+    if ((handle = LoadLibrary(tmpbuf)) == 0) {
+        return;
+    }
+    /* Get the function address */
+    PreJVMStart = (PREJVMSTART)GetProcAddress(handle, "preJVMStart");
+    if (PreJVMStart == NULL) {
+        FreeLibrary(handle);
+        return;
+    }
+    PreJVMStart();
+    FreeLibrary(handle);
+    return;
+}
+
 /*
  * Find path to JRE based on .exe's location or registry settings.
  */
@@ -196,7 +297,6 @@
 LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
 {
     HINSTANCE handle;
-    char crtpath[MAXPATHLEN];
 
     JLI_TraceLauncher("JVM path is %s\n", jvmpath);
 
@@ -206,26 +306,8 @@
      * there (or "JRE path" fails to resolve), skip the explicit load and let
      * nature take its course, which is likely to be a failure to execute.
      *
-     * (NOTE: the above statement is only true for Visual Studio 2003 and
-     *  msvcr71.dll.)
      */
-#ifdef _MSC_VER
-#if _MSC_VER < 1400
-#define CRT_DLL "msvcr71.dll"
-#endif
-#ifdef CRT_DLL
-    if (GetJREPath(crtpath, MAXPATHLEN)) {
-        (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL);   /* Add crt dll */
-        JLI_TraceLauncher("CRT path is %s\n", crtpath);
-        if (_access(crtpath, 0) == 0) {
-            if (LoadLibrary(crtpath) == 0) {
-                JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
-                return JNI_FALSE;
-            }
-        }
-    }
-#endif /* CRT_DLL */
-#endif /* _MSC_VER */
+    LoadMSVCRT();
 
     /* Load the Java VM DLL */
     if ((handle = LoadLibrary(jvmpath)) == 0) {