jdk/src/windows/bin/java_md.c

Print this page
rev 5689 : 8002091: tools/launcher/ToolsOpts.java test started to fail since 7u11 b01 on Windows
Reviewed-by: darcy, jjh, mschoene


  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++) {