1892N/A * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 1892N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1892N/A * This code is free software; you can redistribute it and/or modify it 1892N/A * under the terms of the GNU General Public License version 2 only, as 1892N/A * published by the Free Software Foundation. 1892N/A * This code is distributed in the hope that it will be useful, but WITHOUT 1892N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1892N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1892N/A * version 2 for more details (a copy is included in the LICENSE file that 1892N/A * You should have received a copy of the GNU General Public License version 1892N/A * 2 along with this work; if not, write to the Free Software Foundation, 1892N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1892N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1892N/A/* We supports warmup for UI stack that is performed in parallel 1892N/A * This helps to improve startup of UI application as warmup phase 1892N/A * might be long due to initialization of OS or hardware resources. 1892N/A * It is not CPU bound and therefore it does not interfere with VM init. 1892N/A * Obviously such warmup only has sense for UI apps and therefore it needs 1892N/A * to be explicitly requested by passing -Dsun.awt.warmup=true property 1892N/A * Implementation launches new thread after VM starts and use it to perform 1892N/A * warmup code (platform dependent). 1892N/A * This thread is later reused as AWT toolkit thread as graphics toolkit 1892N/A * often assume that they are used from the same thread they were launched on. 1892N/A * At the moment we only support warmup for D3D. It only possible on windows 1892N/A * and only if other flags do not prohibit this (e.g. OpenGL support requested). 1892N/A #
ifdef _X86_ /* for now disable AWT preloading for 64bit */ 1892N/A/* "AWT was preloaded" flag; 1892N/A * Turned on by AWTPreload(). 1892N/A/* Calls a function with the name specified. 1892N/A * The function must be int(*fn)(void). 1892N/A/* -1: not initialized; 0: OFF, 1: ON */ 1892N/A/* Command line parameter to swith D3D preloading on. */ 1892N/A/* Extracts value of a parameter with the specified name 1892N/A * from command line argument (returns pointer in the argument). 1892N/A * Returns NULL if the argument does not contains the parameter. 1892N/A * GetParamValue("theParam", "theParam=value") returns pointer to "value". 1892N/A // arg[nameLen] is valid (may contain final NULL) 1892N/A/* Checks if commandline argument contains property specified 1892N/A * Returns -1 if the argument does not contain the parameter; 1892N/A * Returns 1 if the argument contains the parameter and its value is "true"; 1892N/A * Returns 0 if the argument contains the parameter and its value is "false". 1892N/A#
endif /* ENABLE_AWT_PRELOAD */ 1892N/A /* Find out where the JRE is that we will be using. */ 1892N/A /* Find the specified JVM type */ 1892N/A /* If we got here, jvmpath has been correctly initialized. */ 1892N/A * gamma launcher is simpler in that it doesn't handle VM flavors, data 1892N/A * model, etc. Assuming everything is set-up correctly 1892N/A * all we need to do here is to return correct path names. See also 1892N/A * GetJVMPath() and GetApplicationHome(). 1892N/A * The Microsoft C Runtime Library needs to be loaded first. A copy is 1892N/A * assumed to be present in the "JRE path" directory. If it is not found 1892N/A * there (or "JRE path" fails to resolve), skip the explicit load and let 1892N/A * nature take its course, which is likely to be a failure to execute. 1892N/A * The preJVMStart is a function in the jkernel.dll, which 1892N/A * performs the final step of synthesizing back the decomposed 1892N/A * modules (partial install) to the full JRE. Any tool which 1892N/A * uses the JRE must peform this step to ensure the complete synthesis. 1892N/A * The EnsureJreInstallation function calls preJVMStart based on 1892N/A * the conditions outlined below, noting that the operation 1892N/A * will fail silently if any of conditions are not met. 1892N/A * NOTE: this call must be made before jvm.dll is loaded, or jvm.cfg 1892N/A * is read, since jvm.cfg will be modified by the preJVMStart. 1892N/A * 1. Are we on a supported platform. 1892N/A * 2. Find the location of the JRE or the Kernel JRE. 1892N/A * 4. check jkernel.dll and invoke the entry-point 1892N/A /* 32 bit windows only please */ 1892N/A /* Does our bundle directory exist ? */ 1892N/A /* Does our jkernel dll exist ? */ 1892N/A /* The Microsoft C Runtime Library needs to be loaded first. */ 1892N/A printf(
"EnsureJreInstallation:could not load C runtime DLL\n");
1892N/A /* Get the function address */ 1892N/A printf(
"EnsureJreInstallation:preJVMStart:function lookup failed\n");
1892N/A * Find path to JRE based on .exe's location or registry settings. 1892N/A /* Is JRE co-located with the application? */ 1892N/A /* Does this app ship a private JRE in <apphome>\jre directory? */ 1892N/A /* Look for a public JRE on this machine. */ 1892N/A * Given a JRE location and a JVM type, construct what the name the 1892N/A * JVM shared library will be. Return true, if such a library 1892N/A * For gamma launcher, JVM is either built-in or in the same directory. 1892N/A * Either way we return "<exe_path>/jvm.dll" where <exe_path> is the 1892N/A * directory where gamma launcher is located. 1892N/A /* this case shouldn't happen */ 1892N/A * Load a jvm from "jvmpath" and initialize the invocation functions. 1892N/A /* JVM is directly linked with gamma launcher; no Loadlibrary() */ 1892N/A /* The Microsoft C Runtime Library needs to be loaded first. */ 1892N/A /* Now get the function addresses */ 1892N/A * If app is "c:\foo\bin\javac", then put "c:\foo" into buf. 1892N/A /* This happens if the application is in a drive root, and 1892N/A * there is no bin directory. */ 1892N/A *
cp =
'\0';
/* remove the bin\ part */ 1934N/A // find the path to the currect executable 1934N/A printf(
"Could not get directory of current executable.");
1934N/A // remove last path component ("hotspot.exe") 1934N/A printf(
"Could not parse directory of current executable.\n");
1892N/A * Helpers to look in the registry for a public JRE. 1892N/A /* Same for 1.5.0, 1.5.1, 1.5.2 etc. */ 1892N/A * Note: There is a very similar implementation of the following 1892N/A * registry reading code in the Windows java control panel (javacp.cpl). 1892N/A * If there are bugs here, a similar bug probably exists there. Hence, 1892N/A * changes here require inspection there. 1892N/A /* Find the current version of the JRE */ 1892N/A /* Find directory where the current version is installed. */ 1892N/A * Support for doing cheap, accurate interval timing. 1892N/A * The format argument must be a printf format string with one %s 1892N/A * argument, which is passed the string argument. 1892N/A * As ReportErrorMessage2 (above) except the system message (if any) 1892N/A * associated with this error is written to a second %s format specifier 1892N/A if (n >
2) {
/* Drop final CR, LF */ 1892N/A }
else /* C runtime error that has no corresponding DOS error code */ 1892N/A * This code should be replaced by code which opens a window with 1892N/A * the exception detail message. 1892N/A * Return JNI_TRUE for an option string that has no effect but should 1892N/A * _not_ be passed on to the vm; return JNI_FALSE otherwise. On 1892N/A * windows, there are no options that should be screened in this 1892N/A /* Tests the command line parameter only if not set yet. */ 1892N/A /* Don't test the command line parameters if already disabled. */ 1892N/A#
endif /* ENABLE_AWT_PRELOAD */ 1892N/A * Determine if there is an acceptable JRE in the registry directory top_key. 1892N/A * Upon locating the "best" one, return a fully qualified path to it. 1892N/A * "Best" is defined as the most advanced JRE meeting the constraints 1892N/A * contained in the manifest_info. If no JRE in this directory meets the 1892N/A * constraints, return NULL. 1892N/A * It doesn't matter if we get an error reading the registry, or we just 1892N/A * don't find anything interesting in the directory. We just return NULL 1892N/A * searching for the best available version. 1892N/A * Extract "JavaHome" from the "best" registry directory and return 1892N/A * that path. If no appropriate version was located, or there is an 1892N/A * error in extracting the "JavaHome" string, return null. 1892N/A * This is the global entry point. It examines the host for the optimal 1892N/A * JRE to be used by scanning a set of registry entries. This set of entries 1892N/A * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment" 1892N/A * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }". 1892N/A * This routine simply opens each of these registry directories before passing 1892N/A * control onto ProcessDir(). 1892N/A * Local helper routine to isolate a single token (option or argument) 1892N/A * This routine accepts a pointer to a character pointer. The first 1892N/A * token (as defined by MSDN command-line argument syntax) is isolated 1892N/A * Upon return, the input character pointer pointed to by the parameter s 1892N/A * is updated to point to the remainding, unscanned, portion of the string, 1892N/A * or to a null character if the entire string has been consummed. 1892N/A * This function returns a pointer to a null-terminated string which 1892N/A * contains the isolated first token, or to the null character if no 1892N/A * Note the side effect of modifying the input string s by the insertion 1892N/A * of a null character, making it two strings. 1892N/A * See "Parsing C Command-Line Arguments" in the MSDN Library for the 1892N/A * parsing rule details. The rule summary from that specification is: 1892N/A * * Arguments are delimited by white space, which is either a space or a tab. 1892N/A * * A string surrounded by double quotation marks is interpreted as a single 1892N/A * argument, regardless of white space contained within. A quoted string can 1892N/A * be embedded in an argument. Note that the caret (^) is not recognized as 1892N/A * an escape character or delimiter. 1892N/A * * A double quotation mark preceded by a backslash, \", is interpreted as a 1892N/A * literal double quotation mark ("). 1892N/A * * Backslashes are interpreted literally, unless they immediately precede a 1892N/A * * If an even number of backslashes is followed by a double quotation mark, 1892N/A * then one backslash (\) is placed in the argv array for every pair of 1892N/A * backslashes (\\), and the double quotation mark (") is interpreted as a 1892N/A * * If an odd number of backslashes is followed by a double quotation mark, 1892N/A * then one backslash (\) is placed in the argv array for every pair of 1892N/A * backslashes (\\) and the double quotation mark is interpreted as an 1892N/A * escape sequence by the remaining backslash, causing a literal double 1892N/A * quotation mark (") to be placed in argv. 1892N/A * Strip leading whitespace, which MSDN defines as only space or tab. 1892N/A * (Hence, no locale specific "isspace" here.) 1892N/A while (*p != (
char)0 && (*p ==
' ' || *p ==
'\t'))
1892N/A head = p;
/* Save the start of the token to return */ 1892N/A * Isolate a token from the command line. 1892N/A while (*p != (
char)0 && (
inquote || !(*p ==
' ' || *p ==
'\t'))) {
1892N/A * If the token isolated isn't already terminated in a "char zero", 1892N/A * then replace the whitespace character with one and move to the 1892N/A * Update the parameter to point to the head of the remaining string 1892N/A * reflecting the command line and return a pointer to the leading 1892N/A * token which was isolated from the command line. 1892N/A * Local helper routine to return a string equivalent to the input string 1892N/A * s, but with quotes removed so the result is a string as would be found 1892N/A * in argv[]. The returned string should be freed by a call to JLI_MemFree(). 1892N/A * The rules for quoting (and escaped quotes) are: 1892N/A * 1 A double quotation mark preceded by a backslash, \", is interpreted as a 1892N/A * literal double quotation mark ("). 1892N/A * 2 Backslashes are interpreted literally, unless they immediately precede a 1892N/A * 3 If an even number of backslashes is followed by a double quotation mark, 1892N/A * then one backslash (\) is placed in the argv array for every pair of 1892N/A * backslashes (\\), and the double quotation mark (") is interpreted as a 1892N/A * 4 If an odd number of backslashes is followed by a double quotation mark, 1892N/A * then one backslash (\) is placed in the argv array for every pair of 1892N/A * backslashes (\\) and the double quotation mark is interpreted as an 1892N/A * escape sequence by the remaining backslash, causing a literal double 1892N/A * quotation mark (") to be placed in argv. 1892N/A const char *p = s;
/* Pointer to the tail of the original string */ 1892N/A char *
pun =
un;
/* Pointer to the tail of the unquoted string */ 1892N/A }
while (*p ==
'\\' && p < q);
1892N/A * Given a path to a jre to execute, this routine checks if this process 1892N/A * is indeed that jre. If not, it exec's that jre. 1892N/A * We want to actually check the paths rather than just the version string 1892N/A * built into the executable, so that given version specification will yield 1892N/A * the exact same Java environment, regardless of the version of the arbitrary 1892N/A * Determine the executable we are building (or in the rare case, running). 1892N/A#
else /* java, oldjava, javaw and friends */ 1892N/A * Resolve the real path to the currently running launcher. 1892N/A "Unable to resolve path to current %s executable: %s",
1892N/A * If the path to the selected JRE directory is a match to the initial 1892N/A * portion of the path to the currently executing JRE, we have a winner! 1892N/A * If so, just return. (strnicmp() is the Windows equiv. of strncasecmp().) 1892N/A return;
/* I am the droid you were looking for */ 1892N/A * If this isn't the selected version, exec the selected version. 1892N/A * Although Windows has an execv() entrypoint, it doesn't actually 1892N/A * overlay a process: it can only create a new process and terminate 1892N/A * the old process. Therefore, any processes waiting on the initial 1892N/A * process wake up and they shouldn't. Hence, a chain of pseudo-zombie 1892N/A * processes must be retained to maintain the proper wait semantics. 1892N/A * Fortunately the image size of the launcher isn't too large at this 1892N/A * If it weren't for this semantic flaw, the code below would be ... 1892N/A * ReportErrorMessage2("Exec of %s failed\n", path, JNI_TRUE); 1892N/A * The incorrect exec semantics could be addressed by: 1892N/A * exit((int)spawnv(_P_WAIT, path, argv)); 1892N/A * this from completely working. All the Windows POSIX process creation 1892N/A * interfaces are implemented as wrappers around the native Windows 1892N/A * function CreateProcess(). CreateProcess() takes a single string 1892N/A * to specify command line options and arguments, so the POSIX routine 1892N/A * wrappers build a single string from the argv[] array and in the 1892N/A * process, any quoting information is lost. 1892N/A * The solution to this to get the original command line, to process it 1892N/A * to remove the new multiple JRE options (if any) as was done for argv 1892N/A * in the common SelectVersion() routine and finally to pass it directly 1892N/A * to the native CreateProcess() Windows process control interface. 1892N/A * The following code block gets and processes the original command 1892N/A * line, replacing the argv[0] equivalent in the command line with 1892N/A * the path to the new executable and removing the appropriate 1892N/A * Multiple JRE support options. Note that similar logic exists 1892N/A * in the platform independent SelectVersion routine, but is 1892N/A * replicated here due to the syntax of CreateProcess(). 1892N/A * The magic "+ 4" characters added to the command line length are 1892N/A * 2 possible quotes around the path (argv[0]), a space after the 1892N/A * path and a terminating null character. 1892N/A while (*
np != (
char)0) {
/* While more command-line */ 1892N/A if (*p != (
char)0) {
/* If a token was isolated */ 1892N/A if (*p != (
char)0)
/* If a token was isolated */ 1892N/A }
else {
/* End of options */ 1892N/A * The following code is modeled after a model presented in the 1892N/A * Microsoft Technical Article "Moving Unix Applications to 1892N/A * Windows NT" (March 6, 1994) and "Creating Processes" on MSDN 1892N/A * (Februrary 2005). It approximates UNIX spawn semantics with 1892N/A * the parent waiting for termination of the child. 1892N/A * Wrapper for platform dependent unsetenv function. 1892N/A/* --- Splash Screen shared library support --- */ 1892N/A * Block current thread and continue execution in a new thread 1892N/A * STACK_SIZE_PARAM_IS_A_RESERVATION is what we want, but it's not 1892N/A * supported on older version of Windows. Try first with the flag; and 1892N/A * if that fails try again without the flag. See MSDN document or HotSpot 1892N/A /* AWT preloading (AFTER main thread start) */ 1892N/A /* D3D routines checks env.var J2D_D3D if no appropriate 1892N/A * command line params was specified 1892N/A /* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */ 1892N/A /* If awtPreloadD3D is still undefined (-1), test 1892N/A * if it is turned on by J2D_D3D_PRELOAD env.var. 1892N/A * By default it's turned OFF. 1892N/A#
endif /* ENABLE_AWT_PRELOAD */ 1892N/A#
endif /* ENABLE_AWT_PRELOAD */ 1892N/A/* Linux only, empty on windows. */ 1892N/A//============================== 1892N/A // load AWT library once (if several preload function should be called) 1892N/A // awt.dll is not loaded yet 1892N/A // awt.dll depends on jvm.dll & java.dll; 1892N/A // jvm.dll is already loaded, so we need only java.dll; 1892N/A // java.dll depends on MSVCRT lib & verify.dll. 1892N/A // get "preloadStop" func ptr 1892N/A // don't forget to stop preloading 1892N/A * Terminates AWT preloading 1892N/A#
endif /* ENABLE_AWT_PRELOAD */