4680N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2963N/A/* We supports warmup for UI stack that is performed in parallel 2963N/A * This helps to improve startup of UI application as warmup phase 2963N/A * might be long due to initialization of OS or hardware resources. 2963N/A * It is not CPU bound and therefore it does not interfere with VM init. 2963N/A * Obviously such warmup only has sense for UI apps and therefore it needs 2963N/A * to be explicitly requested by passing -Dsun.awt.warmup=true property 2963N/A * Implementation launches new thread after VM starts and use it to perform 2963N/A * warmup code (platform dependent). 2963N/A * This thread is later reused as AWT toolkit thread as graphics toolkit 2963N/A * often assume that they are used from the same thread they were launched on. 2963N/A * At the moment we only support warmup for D3D. It only possible on windows 2963N/A * and only if other flags do not prohibit this (e.g. OpenGL support requested). 3090N/A /* CR6999872: fastdebug crashes if awt library is loaded before JVM is 2963N/A/* "AWT was preloaded" flag; 2963N/A * turned on by AWTPreload(). 2963N/A/* Calls a function with the name specified 2963N/A * the function must be int(*fn)(void). 2963N/A/* -1: not initialized; 0: OFF, 1: ON */ 2963N/A/* command line parameter to swith D3D preloading on */ 2963N/A/* Extracts value of a parameter with the specified name 2963N/A * from command line argument (returns pointer in the argument). 2963N/A * Returns NULL if the argument does not contains the parameter. 2963N/A * GetParamValue("theParam", "theParam=value") returns pointer to "value". 2963N/A /* arg[nameLen] is valid (may contain final NULL) */ 2963N/A/* Checks if commandline argument contains property specified 2963N/A * Returns -1 if the argument does not contain the parameter; 2963N/A * Returns 1 if the argument contains the parameter and its value is "true"; 2963N/A * Returns 0 if the argument contains the parameter and its value is "false". 2963N/A#
endif /* ENABLE_AWT_PRELOAD */ 0N/A * Returns the arch path, to get the current arch use the 0N/A * macro GetArch, nbits here is ignored for now. 0N/A /* Find out where the JRE is that we will be using. */ 0N/A /* Find the specified JVM type */ 0N/A /* If we got here, jvmpath has been correctly initialized. */ 2963N/A /* Check if we need preload AWT */ 2963N/A /* Tests the "turn on" parameter only if not set yet. */ 2963N/A /* Test parameters which can disable preloading if not already disabled. */ 2963N/A /* no need to test the rest of the parameters */ 2963N/A#
endif /* ENABLE_AWT_PRELOAD */ 1365N/A * The Microsoft C Runtime Library needs to be loaded first. A copy is 1365N/A * assumed to be present in the "JRE path" directory. If it is not found 1365N/A * there (or "JRE path" fails to resolve), skip the explicit load and let 1365N/A * nature take its course, which is likely to be a failure to execute. 2324N/A * This is clearly completely specific to the exact compiler version 2324N/A * which isn't very nice, but its hardly the only place. 2324N/A * No attempt to look for compiler versions in between 2003 and 2010 2324N/A * as we aren't supporting building with those. 0N/A * Find path to JRE based on .exe's location or registry settings. 0N/A /* Is JRE co-located with the application? */ 0N/A /* Does this app ship a private JRE in <apphome>\jre directory? */ 0N/A /* Look for a public JRE on this machine. */ 0N/A * Given a JRE location and a JVM type, construct what the name the 0N/A * JVM shared library will be. Return true, if such a library 0N/A * exists, false otherwise. 0N/A * Load a jvm from "jvmpath" and initialize the invocation functions. 0N/A * The Microsoft C Runtime Library needs to be loaded first. A copy is 0N/A * assumed to be present in the "JRE path" directory. If it is not found 0N/A * there (or "JRE path" fails to resolve), skip the explicit load and let 0N/A * nature take its course, which is likely to be a failure to execute. 0N/A /* Load the Java VM DLL */ 0N/A /* Now get the function addresses */ 0N/A * If app is "c:\foo\bin\javac", then put "c:\foo" into buf. 0N/A /* This happens if the application is in a drive root, and 0N/A * there is no bin directory. */ 0N/A *
cp =
'\0';
/* remove the bin\ part */ 0N/A * Helpers to look in the registry for a public JRE. 0N/A /* Same for 1.5.0, 1.5.1, 1.5.2 etc. */ 0N/A#
define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment" 0N/A * Note: There is a very similar implementation of the following 0N/A * registry reading code in the Windows java control panel (javacp.cpl). 0N/A * If there are bugs here, a similar bug probably exists there. Hence, 0N/A * changes here require inspection there. 0N/A /* Find the current version of the JRE */ 0N/A /* Find directory where the current version is installed. */ 0N/A printf(
"Warning: Can't read MicroVersion\n");
0N/A * Support for doing cheap, accurate interval timing. 5694N/A * windows snprintf does not guarantee a null terminator in the buffer, 5694N/A * if the computed size is equal to or greater than the buffer size, 5700N/A * as well as error conditions. This function guarantees a null terminator 5700N/A * under all these conditions. An unreasonable buffer or size will return 5700N/A * an error value. Under all other conditions this function will return the 5700N/A * size of the bytes actually written minus the null terminator, similar 5700N/A * to ansi snprintf api. Thus when calling this function the caller must 5700N/A * ensure storage for the null terminator. 5694N/A /* force a null terminator, if something is amiss */ 5700N/A /* force a null terminator */ 0N/A /* get the length of the string we need */ 517N/A * Just like JLI_ReportErrorMessage, except that it concatenates the system 0N/A * error message if any, its upto the calling routine to correctly 0N/A * format the separation of the messages. 0N/A if (n >
2) {
/* Drop final CR, LF */ 0N/A }
else {
/* C runtime error that has no corresponding DOS error code */ 0N/A /* get the length of the string we need */ 0N/A * This code should be replaced by code which opens a window with 0N/A * the exception detail message, for now atleast put a dialog up. 0N/A * Determine if there is an acceptable JRE in the registry directory top_key. 0N/A * Upon locating the "best" one, return a fully qualified path to it. 0N/A * "Best" is defined as the most advanced JRE meeting the constraints 0N/A * contained in the manifest_info. If no JRE in this directory meets the 0N/A * constraints, return NULL. 0N/A * It doesn't matter if we get an error reading the registry, or we just 0N/A * don't find anything interesting in the directory. We just return NULL 0N/A * searching for the best available version. 0N/A * Extract "JavaHome" from the "best" registry directory and return 0N/A * that path. If no appropriate version was located, or there is an 0N/A * error in extracting the "JavaHome" string, return null. 0N/A * This is the global entry point. It examines the host for the optimal 0N/A * JRE to be used by scanning a set of registry entries. This set of entries 0N/A * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment" 0N/A * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }". 0N/A * This routine simply opens each of these registry directories before passing 0N/A * control onto ProcessDir(). 0N/A * Local helper routine to isolate a single token (option or argument) 0N/A * from the command line. 0N/A * This routine accepts a pointer to a character pointer. The first 0N/A * token (as defined by MSDN command-line argument syntax) is isolated 0N/A * Upon return, the input character pointer pointed to by the parameter s 0N/A * is updated to point to the remainding, unscanned, portion of the string, 0N/A * or to a null character if the entire string has been consummed. 0N/A * This function returns a pointer to a null-terminated string which 0N/A * contains the isolated first token, or to the null character if no 0N/A * token could be isolated. 0N/A * Note the side effect of modifying the input string s by the insertion 0N/A * of a null character, making it two strings. 0N/A * See "Parsing C Command-Line Arguments" in the MSDN Library for the 0N/A * parsing rule details. The rule summary from that specification is: 0N/A * * Arguments are delimited by white space, which is either a space or a tab. 0N/A * * A string surrounded by double quotation marks is interpreted as a single 0N/A * argument, regardless of white space contained within. A quoted string can 0N/A * be embedded in an argument. Note that the caret (^) is not recognized as 0N/A * an escape character or delimiter. 0N/A * * A double quotation mark preceded by a backslash, \", is interpreted as a 0N/A * literal double quotation mark ("). 0N/A * * Backslashes are interpreted literally, unless they immediately precede a 0N/A * double quotation mark. 0N/A * * If an even number of backslashes is followed by a double quotation mark, 0N/A * then one backslash (\) is placed in the argv array for every pair of 0N/A * backslashes (\\), and the double quotation mark (") is interpreted as a 0N/A * * If an odd number of backslashes is followed by a double quotation mark, 0N/A * then one backslash (\) is placed in the argv array for every pair of 0N/A * backslashes (\\) and the double quotation mark is interpreted as an 0N/A * escape sequence by the remaining backslash, causing a literal double 0N/A * quotation mark (") to be placed in argv. 0N/A * Strip leading whitespace, which MSDN defines as only space or tab. 0N/A * (Hence, no locale specific "isspace" here.) 0N/A while (*p != (
char)0 && (*p ==
' ' || *p ==
'\t'))
0N/A head = p;
/* Save the start of the token to return */ 0N/A * Isolate a token from the command line. 0N/A while (*p != (
char)0 && (
inquote || !(*p ==
' ' || *p ==
'\t'))) {
0N/A if (*p ==
'\\' && *(p+
1) ==
'"' &&
slashes %
2 == 0)
0N/A * If the token isolated isn't already terminated in a "char zero", 0N/A * then replace the whitespace character with one and move to the 0N/A * Update the parameter to point to the head of the remaining string 0N/A * reflecting the command line and return a pointer to the leading 0N/A * token which was isolated from the command line. 0N/A * Local helper routine to return a string equivalent to the input string 0N/A * s, but with quotes removed so the result is a string as would be found 0N/A * in argv[]. The returned string should be freed by a call to JLI_MemFree(). 0N/A * The rules for quoting (and escaped quotes) are: 0N/A * 1 A double quotation mark preceded by a backslash, \", is interpreted as a 0N/A * literal double quotation mark ("). 0N/A * 2 Backslashes are interpreted literally, unless they immediately precede a 0N/A * double quotation mark. 0N/A * 3 If an even number of backslashes is followed by a double quotation mark, 0N/A * then one backslash (\) is placed in the argv array for every pair of 0N/A * backslashes (\\), and the double quotation mark (") is interpreted as a 0N/A * 4 If an odd number of backslashes is followed by a double quotation mark, 0N/A * then one backslash (\) is placed in the argv array for every pair of 0N/A * backslashes (\\) and the double quotation mark is interpreted as an 0N/A * escape sequence by the remaining backslash, causing a literal double 0N/A * quotation mark (") to be placed in argv. 0N/A const char *p = s;
/* Pointer to the tail of the original string */ 0N/A char *
pun =
un;
/* Pointer to the tail of the unquoted string */ 0N/A while (*p !=
'\0') {
0N/A }
else if (*p ==
'\\') {
0N/A }
while (*p ==
'\\' && p < q);
0N/A * Given a path to a jre to execute, this routine checks if this process 0N/A * is indeed that jre. If not, it exec's that jre. 0N/A * We want to actually check the paths rather than just the version string 0N/A * built into the executable, so that given version specification will yield 0N/A * the exact same Java environment, regardless of the version of the arbitrary 0N/A * launcher we start with. 0N/A * Resolve the real path to the currently running launcher. 0N/A * If the path to the selected JRE directory is a match to the initial 0N/A * portion of the path to the currently executing JRE, we have a winner! 0N/A * If so, just return. 0N/A return;
/* I am the droid you were looking for */ 0N/A * If this isn't the selected version, exec the selected version. 0N/A * Although Windows has an execv() entrypoint, it doesn't actually 0N/A * overlay a process: it can only create a new process and terminate 0N/A * the old process. Therefore, any processes waiting on the initial 0N/A * process wake up and they shouldn't. Hence, a chain of pseudo-zombie 0N/A * processes must be retained to maintain the proper wait semantics. 0N/A * Fortunately the image size of the launcher isn't too large at this 0N/A * If it weren't for this semantic flaw, the code below would be ... 0N/A * execv(path, argv); 517N/A * JLI_ReportErrorMessage("Error: Exec of %s failed\n", path); 0N/A * The incorrect exec semantics could be addressed by: 0N/A * exit((int)spawnv(_P_WAIT, path, argv)); 0N/A * Unfortunately, a bug in Windows spawn/exec impementation prevents 0N/A * this from completely working. All the Windows POSIX process creation 0N/A * interfaces are implemented as wrappers around the native Windows 0N/A * function CreateProcess(). CreateProcess() takes a single string 0N/A * to specify command line options and arguments, so the POSIX routine 0N/A * wrappers build a single string from the argv[] array and in the 0N/A * process, any quoting information is lost. 0N/A * The solution to this to get the original command line, to process it 0N/A * to remove the new multiple JRE options (if any) as was done for argv 0N/A * in the common SelectVersion() routine and finally to pass it directly 0N/A * to the native CreateProcess() Windows process control interface. 0N/A * The following code block gets and processes the original command 0N/A * line, replacing the argv[0] equivalent in the command line with 0N/A * the path to the new executable and removing the appropriate 0N/A * Multiple JRE support options. Note that similar logic exists 0N/A * in the platform independent SelectVersion routine, but is 0N/A * replicated here due to the syntax of CreateProcess(). 0N/A * The magic "+ 4" characters added to the command line length are 0N/A * 2 possible quotes around the path (argv[0]), a space after the 0N/A * path and a terminating null character. 0N/A while (*
np != (
char)0) {
/* While more command-line */ 0N/A if (*p != (
char)0) {
/* If a token was isolated */ 0N/A if (*p != (
char)0)
/* If a token was isolated */ 0N/A }
else {
/* End of options */ 0N/A * The following code is modeled after a model presented in the 0N/A * Microsoft Technical Article "Moving Unix Applications to 0N/A * Windows NT" (March 6, 1994) and "Creating Processes" on MSDN 0N/A * (Februrary 2005). It approximates UNIX spawn semantics with 0N/A * the parent waiting for termination of the child. 0N/A * Wrapper for platform dependent unsetenv function. 0N/A/* --- Splash Screen shared library support --- */ 0N/A * Block current thread and continue execution in a new thread 0N/A * STACK_SIZE_PARAM_IS_A_RESERVATION is what we want, but it's not 0N/A * supported on older version of Windows. Try first with the flag; and 0N/A * if that fails try again without the flag. See MSDN document or HotSpot 2963N/A /* AWT preloading (AFTER main thread start) */ 2963N/A /* D3D routines checks env.var J2D_D3D if no appropriate 2963N/A * command line params was specified 2963N/A /* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */ 2963N/A /* If awtPreloadD3D is still undefined (-1), test 2963N/A * if it is turned on by J2D_D3D_PRELOAD env.var. 2963N/A * By default it's turned OFF. 2963N/A#
endif /* ENABLE_AWT_PRELOAD */ 2963N/A#
endif /* ENABLE_AWT_PRELOAD */ 647N/A/* Unix only, empty on windows. */ 647N/A * The implementation for finding classes from the bootstrap 647N/A /* need to use the demangled entry point */ 1645N/A "JVM_FindClassFromBootLoader");
16N/A * Required for javaw mode MessageBox output as well as for 16N/A * HotSpot -XX:+ShowMessageBoxOnError in java mode, an empty 16N/A * flag field is sufficient to perform the basic UI initialization. 2963N/A/* ============================== */ 2963N/A /* load AWT library once (if several preload function should be called) */ 2963N/A /* awt.dll is not loaded yet */ 2963N/A /* awt.dll depends on jvm.dll & java.dll; 2963N/A * jvm.dll is already loaded, so we need only java.dll; 2963N/A * java.dll depends on MSVCRT lib & verify.dll. 2963N/A /* get "preloadStop" func ptr */ 2963N/A /* don't forget to stop preloading */ 2963N/A * Terminates AWT preloading 2963N/A#
endif /* ENABLE_AWT_PRELOAD */ 4680N/A // stubbed out for windows and *nixes. 4680N/A // stubbed out for windows and *nixes. 4680N/A * on windows, we return a false to indicate this option is not applicable 5563N/A * At this point we have the arguments to the application, and we need to 5563N/A * check with original stdargs in order to compare which of these truly 5563N/A * needs expansion. cmdtoargs will specify this if it finds a bare 5563N/A * (unquoted) argument containing a glob character(s) ie. * or ? 5563N/A // the holy grail we need to compare with. 5563N/A // sanity check, this should never happen 5563N/A // sanity check, match the args we have, to the holy grail 5563N/A // sanity check, ensure that the first argument of the arrays are the same 5563N/A // some thing is amiss the args don't match 5563N/A // make a copy of the args which will be expanded in java if required. 5563N/A // indicator char + String + NULL terminator, the java method will strip 5563N/A // out the first character, the indicator character, so no matter what 5563N/A // clean up any allocated memory and return back the old arguments 5563N/A // expand the arguments that require expansion, the java method will strip 5563N/A // out the indicator character.