84
85 /* Calls a function with the name specified
86 * the function must be int(*fn)(void).
87 */
88 int AWTPreload(const char *funcName);
89 /* stops AWT preloading */
90 void AWTPreloadStop();
91
92 /* D3D preloading */
93 /* -1: not initialized; 0: OFF, 1: ON */
94 int awtPreloadD3D = -1;
95 /* command line parameter to swith D3D preloading on */
96 #define PARAM_PRELOAD_D3D "-Dsun.awt.warmup"
97 /* D3D/OpenGL management parameters */
98 #define PARAM_NODDRAW "-Dsun.java2d.noddraw"
99 #define PARAM_D3D "-Dsun.java2d.d3d"
100 #define PARAM_OPENGL "-Dsun.java2d.opengl"
101 /* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
102 #define D3D_PRELOAD_FUNC "preloadD3D"
103
104
105 /* Extracts value of a parameter with the specified name
106 * from command line argument (returns pointer in the argument).
107 * Returns NULL if the argument does not contains the parameter.
108 * e.g.:
109 * GetParamValue("theParam", "theParam=value") returns pointer to "value".
110 */
111 const char * GetParamValue(const char *paramName, const char *arg) {
112 int nameLen = JLI_StrLen(paramName);
113 if (JLI_StrNCmp(paramName, arg, nameLen) == 0) {
114 /* arg[nameLen] is valid (may contain final NULL) */
115 if (arg[nameLen] == '=') {
116 return arg + nameLen + 1;
117 }
118 }
119 return NULL;
120 }
121
122 /* Checks if commandline argument contains property specified
123 * and analyze it as boolean property (true/false).
124 * Returns -1 if the argument does not contain the parameter;
259 if (!loaded) {
260 /*
261 * The Microsoft C Runtime Library needs to be loaded first. A copy is
262 * assumed to be present in the "JRE path" directory. If it is not found
263 * there (or "JRE path" fails to resolve), skip the explicit load and let
264 * nature take its course, which is likely to be a failure to execute.
265 * This is clearly completely specific to the exact compiler version
266 * which isn't very nice, but its hardly the only place.
267 * No attempt to look for compiler versions in between 2003 and 2010
268 * as we aren't supporting building with those.
269 */
270 #ifdef _MSC_VER
271 #if _MSC_VER < 1400
272 #define CRT_DLL "msvcr71.dll"
273 #endif
274 #if _MSC_VER >= 1600
275 #define CRT_DLL "msvcr100.dll"
276 #endif
277 #ifdef CRT_DLL
278 if (GetJREPath(crtpath, MAXPATHLEN)) {
279 if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") + JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
280 JLI_ReportErrorMessage(JRE_ERROR11);
281 return JNI_FALSE;
282 }
283 (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
284 JLI_TraceLauncher("CRT path is %s\n", crtpath);
285 if (_access(crtpath, 0) == 0) {
286 if (LoadLibrary(crtpath) == 0) {
287 JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
288 return JNI_FALSE;
289 }
290 }
291 }
292 #endif /* CRT_DLL */
293 #endif /* _MSC_VER */
294 loaded = 1;
295 }
296 return JNI_TRUE;
297 }
298
299
330 }
331
332 JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
333 return JNI_FALSE;
334
335 }
336
337 /*
338 * Given a JRE location and a JVM type, construct what the name the
339 * JVM shared library will be. Return true, if such a library
340 * exists, false otherwise.
341 */
342 static jboolean
343 GetJVMPath(const char *jrepath, const char *jvmtype,
344 char *jvmpath, jint jvmpathsize)
345 {
346 struct stat s;
347 if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) {
348 JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype);
349 } else {
350 JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
351 }
352 if (stat(jvmpath, &s) == 0) {
353 return JNI_TRUE;
354 } else {
355 return JNI_FALSE;
356 }
357 }
358
359 /*
360 * Load a jvm from "jvmpath" and initialize the invocation functions.
361 */
362 jboolean
363 LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
364 {
365 HINSTANCE handle;
366
367 JLI_TraceLauncher("JVM path is %s\n", jvmpath);
368
369 /*
370 * The Microsoft C Runtime Library needs to be loaded first. A copy is
508 LARGE_INTEGER count;
509
510 if (!counterInitialized) {
511 counterAvailable = QueryPerformanceFrequency(&counterFrequency);
512 counterInitialized = JNI_TRUE;
513 }
514 if (!counterAvailable) {
515 return 0;
516 }
517 QueryPerformanceCounter(&count);
518 return (jlong)(count.QuadPart);
519 }
520
521 jlong Counter2Micros(jlong counts)
522 {
523 if (!counterAvailable || !counterInitialized) {
524 return 0;
525 }
526 return (counts * 1000 * 1000)/counterFrequency.QuadPart;
527 }
528
529 void
530 JLI_ReportErrorMessage(const char* fmt, ...) {
531 va_list vl;
532 va_start(vl,fmt);
533
534 if (IsJavaw()) {
535 char *message;
536
537 /* get the length of the string we need */
538 int n = _vscprintf(fmt, vl);
539
540 message = (char *)JLI_MemAlloc(n + 1);
541 _vsnprintf(message, n, fmt, vl);
542 message[n]='\0';
543 MessageBox(NULL, message, "Java Virtual Machine Launcher",
544 (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
545 JLI_MemFree(message);
546 } else {
547 vfprintf(stderr, fmt, vl);
863 *pun++ = *p++;
864 } else {
865 *pun++ = *p++;
866 }
867 }
868 *pun = '\0';
869 return un;
870 }
871
872 /*
873 * Given a path to a jre to execute, this routine checks if this process
874 * is indeed that jre. If not, it exec's that jre.
875 *
876 * We want to actually check the paths rather than just the version string
877 * built into the executable, so that given version specification will yield
878 * the exact same Java environment, regardless of the version of the arbitrary
879 * launcher we start with.
880 */
881 void
882 ExecJRE(char *jre, char **argv) {
883 int len;
884 char path[MAXPATHLEN + 1];
885
886 const char *progname = GetProgramName();
887
888 /*
889 * Resolve the real path to the currently running launcher.
890 */
891 len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
892 if (len == 0 || len > MAXPATHLEN) {
893 JLI_ReportErrorMessageSys(JRE_ERROR9, progname);
894 exit(1);
895 }
896
897 JLI_TraceLauncher("ExecJRE: old: %s\n", path);
898 JLI_TraceLauncher("ExecJRE: new: %s\n", jre);
899
900 /*
901 * If the path to the selected JRE directory is a match to the initial
902 * portion of the path to the currently executing JRE, we have a winner!
903 * If so, just return.
1400 // some thing is amiss the args don't match
1401 JLI_TraceLauncher("Warning: app args parsing error\n");
1402 JLI_TraceLauncher("passing arguments as-is\n");
1403 return NewPlatformStringArray(env, strv, argc);
1404 }
1405
1406 // make a copy of the args which will be expanded in java if required.
1407 nargv = (char **)JLI_MemAlloc(argc * sizeof(char*));
1408 for (i = 0, j = idx; i < argc; i++, j++) {
1409 jboolean arg_expand = (JLI_StrCmp(stdargs[j].arg, strv[i]) == 0)
1410 ? stdargs[j].has_wildcard
1411 : JNI_FALSE;
1412 if (needs_expansion == JNI_FALSE)
1413 needs_expansion = arg_expand;
1414
1415 // indicator char + String + NULL terminator, the java method will strip
1416 // out the first character, the indicator character, so no matter what
1417 // we add the indicator
1418 tlen = 1 + JLI_StrLen(strv[i]) + 1;
1419 nargv[i] = (char *) JLI_MemAlloc(tlen);
1420 JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F', strv[i]);
1421 JLI_TraceLauncher("%s\n", nargv[i]);
1422 }
1423
1424 if (!needs_expansion) {
1425 // clean up any allocated memory and return back the old arguments
1426 for (i = 0 ; i < argc ; i++) {
1427 JLI_MemFree(nargv[i]);
1428 }
1429 JLI_MemFree(nargv);
1430 return NewPlatformStringArray(env, strv, argc);
1431 }
1432 NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
1433 "expandArgs",
1434 "([Ljava/lang/String;)[Ljava/lang/String;"));
1435
1436 // expand the arguments that require expansion, the java method will strip
1437 // out the indicator character.
1438 inArray = NewPlatformStringArray(env, nargv, argc);
1439 outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray);
1440 for (i = 0; i < argc; i++) {
|
84
85 /* Calls a function with the name specified
86 * the function must be int(*fn)(void).
87 */
88 int AWTPreload(const char *funcName);
89 /* stops AWT preloading */
90 void AWTPreloadStop();
91
92 /* D3D preloading */
93 /* -1: not initialized; 0: OFF, 1: ON */
94 int awtPreloadD3D = -1;
95 /* command line parameter to swith D3D preloading on */
96 #define PARAM_PRELOAD_D3D "-Dsun.awt.warmup"
97 /* D3D/OpenGL management parameters */
98 #define PARAM_NODDRAW "-Dsun.java2d.noddraw"
99 #define PARAM_D3D "-Dsun.java2d.d3d"
100 #define PARAM_OPENGL "-Dsun.java2d.opengl"
101 /* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
102 #define D3D_PRELOAD_FUNC "preloadD3D"
103
104 /* Extracts value of a parameter with the specified name
105 * from command line argument (returns pointer in the argument).
106 * Returns NULL if the argument does not contains the parameter.
107 * e.g.:
108 * GetParamValue("theParam", "theParam=value") returns pointer to "value".
109 */
110 const char * GetParamValue(const char *paramName, const char *arg) {
111 int nameLen = JLI_StrLen(paramName);
112 if (JLI_StrNCmp(paramName, arg, nameLen) == 0) {
113 /* arg[nameLen] is valid (may contain final NULL) */
114 if (arg[nameLen] == '=') {
115 return arg + nameLen + 1;
116 }
117 }
118 return NULL;
119 }
120
121 /* Checks if commandline argument contains property specified
122 * and analyze it as boolean property (true/false).
123 * Returns -1 if the argument does not contain the parameter;
258 if (!loaded) {
259 /*
260 * The Microsoft C Runtime Library needs to be loaded first. A copy is
261 * assumed to be present in the "JRE path" directory. If it is not found
262 * there (or "JRE path" fails to resolve), skip the explicit load and let
263 * nature take its course, which is likely to be a failure to execute.
264 * This is clearly completely specific to the exact compiler version
265 * which isn't very nice, but its hardly the only place.
266 * No attempt to look for compiler versions in between 2003 and 2010
267 * as we aren't supporting building with those.
268 */
269 #ifdef _MSC_VER
270 #if _MSC_VER < 1400
271 #define CRT_DLL "msvcr71.dll"
272 #endif
273 #if _MSC_VER >= 1600
274 #define CRT_DLL "msvcr100.dll"
275 #endif
276 #ifdef CRT_DLL
277 if (GetJREPath(crtpath, MAXPATHLEN)) {
278 if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
279 JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
280 JLI_ReportErrorMessage(JRE_ERROR11);
281 return JNI_FALSE;
282 }
283 (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */
284 JLI_TraceLauncher("CRT path is %s\n", crtpath);
285 if (_access(crtpath, 0) == 0) {
286 if (LoadLibrary(crtpath) == 0) {
287 JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
288 return JNI_FALSE;
289 }
290 }
291 }
292 #endif /* CRT_DLL */
293 #endif /* _MSC_VER */
294 loaded = 1;
295 }
296 return JNI_TRUE;
297 }
298
299
330 }
331
332 JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
333 return JNI_FALSE;
334
335 }
336
337 /*
338 * Given a JRE location and a JVM type, construct what the name the
339 * JVM shared library will be. Return true, if such a library
340 * exists, false otherwise.
341 */
342 static jboolean
343 GetJVMPath(const char *jrepath, const char *jvmtype,
344 char *jvmpath, jint jvmpathsize)
345 {
346 struct stat s;
347 if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) {
348 JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype);
349 } else {
350 JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL,
351 jrepath, jvmtype);
352 }
353 if (stat(jvmpath, &s) == 0) {
354 return JNI_TRUE;
355 } else {
356 return JNI_FALSE;
357 }
358 }
359
360 /*
361 * Load a jvm from "jvmpath" and initialize the invocation functions.
362 */
363 jboolean
364 LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
365 {
366 HINSTANCE handle;
367
368 JLI_TraceLauncher("JVM path is %s\n", jvmpath);
369
370 /*
371 * The Microsoft C Runtime Library needs to be loaded first. A copy is
509 LARGE_INTEGER count;
510
511 if (!counterInitialized) {
512 counterAvailable = QueryPerformanceFrequency(&counterFrequency);
513 counterInitialized = JNI_TRUE;
514 }
515 if (!counterAvailable) {
516 return 0;
517 }
518 QueryPerformanceCounter(&count);
519 return (jlong)(count.QuadPart);
520 }
521
522 jlong Counter2Micros(jlong counts)
523 {
524 if (!counterAvailable || !counterInitialized) {
525 return 0;
526 }
527 return (counts * 1000 * 1000)/counterFrequency.QuadPart;
528 }
529 /*
530 * windows snprintf does not guarantee a null terminator in the buffer,
531 * if the computed size is equal to or greater than the buffer size,
532 * as well as error conditions. This function guarantees a null terminator
533 * under all these conditions. An unreasonable buffer or size will return
534 * an error value. Under all other conditions this function will return the
535 * size of the bytes actually written minus the null terminator, similar
536 * to ansi snprintf api. Thus when calling this function the caller must
537 * ensure storage for the null terminator.
538 */
539 int
540 JLI_Snprintf(char* buffer, size_t size, const char* format, ...) {
541 int rc;
542 va_list vl;
543 if (size == 0 || buffer == NULL)
544 return -1;
545 buffer[0] = '\0';
546 va_start(vl, format);
547 rc = vsnprintf(buffer, size, format, vl);
548 va_end(vl);
549 /* force a null terminator, if something is amiss */
550 if (rc < 0) {
551 /* apply ansi semantics */
552 buffer[size - 1] = '\0';
553 return size;
554 } else if (rc == size) {
555 /* force a null terminator */
556 buffer[size - 1] = '\0';
557 }
558 return rc;
559 }
560
561 void
562 JLI_ReportErrorMessage(const char* fmt, ...) {
563 va_list vl;
564 va_start(vl,fmt);
565
566 if (IsJavaw()) {
567 char *message;
568
569 /* get the length of the string we need */
570 int n = _vscprintf(fmt, vl);
571
572 message = (char *)JLI_MemAlloc(n + 1);
573 _vsnprintf(message, n, fmt, vl);
574 message[n]='\0';
575 MessageBox(NULL, message, "Java Virtual Machine Launcher",
576 (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
577 JLI_MemFree(message);
578 } else {
579 vfprintf(stderr, fmt, vl);
895 *pun++ = *p++;
896 } else {
897 *pun++ = *p++;
898 }
899 }
900 *pun = '\0';
901 return un;
902 }
903
904 /*
905 * Given a path to a jre to execute, this routine checks if this process
906 * is indeed that jre. If not, it exec's that jre.
907 *
908 * We want to actually check the paths rather than just the version string
909 * built into the executable, so that given version specification will yield
910 * the exact same Java environment, regardless of the version of the arbitrary
911 * launcher we start with.
912 */
913 void
914 ExecJRE(char *jre, char **argv) {
915 jint len;
916 char path[MAXPATHLEN + 1];
917
918 const char *progname = GetProgramName();
919
920 /*
921 * Resolve the real path to the currently running launcher.
922 */
923 len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
924 if (len == 0 || len > MAXPATHLEN) {
925 JLI_ReportErrorMessageSys(JRE_ERROR9, progname);
926 exit(1);
927 }
928
929 JLI_TraceLauncher("ExecJRE: old: %s\n", path);
930 JLI_TraceLauncher("ExecJRE: new: %s\n", jre);
931
932 /*
933 * If the path to the selected JRE directory is a match to the initial
934 * portion of the path to the currently executing JRE, we have a winner!
935 * If so, just return.
1432 // some thing is amiss the args don't match
1433 JLI_TraceLauncher("Warning: app args parsing error\n");
1434 JLI_TraceLauncher("passing arguments as-is\n");
1435 return NewPlatformStringArray(env, strv, argc);
1436 }
1437
1438 // make a copy of the args which will be expanded in java if required.
1439 nargv = (char **)JLI_MemAlloc(argc * sizeof(char*));
1440 for (i = 0, j = idx; i < argc; i++, j++) {
1441 jboolean arg_expand = (JLI_StrCmp(stdargs[j].arg, strv[i]) == 0)
1442 ? stdargs[j].has_wildcard
1443 : JNI_FALSE;
1444 if (needs_expansion == JNI_FALSE)
1445 needs_expansion = arg_expand;
1446
1447 // indicator char + String + NULL terminator, the java method will strip
1448 // out the first character, the indicator character, so no matter what
1449 // we add the indicator
1450 tlen = 1 + JLI_StrLen(strv[i]) + 1;
1451 nargv[i] = (char *) JLI_MemAlloc(tlen);
1452 if (JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F',
1453 strv[i]) < 0) {
1454 return NULL;
1455 }
1456 JLI_TraceLauncher("%s\n", nargv[i]);
1457 }
1458
1459 if (!needs_expansion) {
1460 // clean up any allocated memory and return back the old arguments
1461 for (i = 0 ; i < argc ; i++) {
1462 JLI_MemFree(nargv[i]);
1463 }
1464 JLI_MemFree(nargv);
1465 return NewPlatformStringArray(env, strv, argc);
1466 }
1467 NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
1468 "expandArgs",
1469 "([Ljava/lang/String;)[Ljava/lang/String;"));
1470
1471 // expand the arguments that require expansion, the java method will strip
1472 // out the indicator character.
1473 inArray = NewPlatformStringArray(env, nargv, argc);
1474 outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray);
1475 for (i = 0; i < argc; i++) {
|