< prev index next >

src/java.base/windows/native/libjli/java_md.c

Print this page
rev 54213 : 8218547: Simplify JLI_Open on Windows in native code (libjli)


  24  */
  25 
  26 #include <windows.h>
  27 #include <io.h>
  28 #include <process.h>
  29 #include <stdlib.h>
  30 #include <stdio.h>
  31 #include <stdarg.h>
  32 #include <string.h>
  33 #include <sys/types.h>
  34 #include <sys/stat.h>
  35 #include <wtypes.h>
  36 #include <commctrl.h>
  37 
  38 #include <jni.h>
  39 #include "java.h"
  40 
  41 #define JVM_DLL "jvm.dll"
  42 #define JAVA_DLL "java.dll"
  43 
  44 #define ELP_PREFIX L"\\\\?\\"
  45 
  46 /*
  47  * Prototypes.
  48  */
  49 static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
  50                            char *jvmpath, jint jvmpathsize);
  51 static jboolean GetJREPath(char *path, jint pathsize);
  52 
  53 #ifdef USE_REGISTRY_LOOKUP
  54 jboolean GetPublicJREHome(char *buf, jint bufsize);
  55 #endif
  56 
  57 /* We supports warmup for UI stack that is performed in parallel
  58  * to VM initialization.
  59  * This helps to improve startup of UI application as warmup phase
  60  * might be long due to initialization of OS or hardware resources.
  61  * It is not CPU bound and therefore it does not interfere with VM init.
  62  * Obviously such warmup only has sense for UI apps and therefore it needs
  63  * to be explicitly requested by passing -Dsun.awt.warmup=true property
  64  * (this is always the case for plugin/javaws).
  65  *


 480     int rc;
 481     va_list vl;
 482     if (size == 0 || buffer == NULL)
 483         return -1;
 484     buffer[0] = '\0';
 485     va_start(vl, format);
 486     rc = vsnprintf(buffer, size, format, vl);
 487     va_end(vl);
 488     /* force a null terminator, if something is amiss */
 489     if (rc < 0) {
 490         /* apply ansi semantics */
 491         buffer[size - 1] = '\0';
 492         return (int)size;
 493     } else if (rc == size) {
 494         /* force a null terminator */
 495         buffer[size - 1] = '\0';
 496     }
 497     return rc;
 498 }
 499 
 500 /* On Windows, if _open fails, retry again with CreateFileW and
 501  *  "\\?\" prefix ( extended-length paths) - this allows to open paths with larger file names;
 502  * otherwise we run into the MAX_PATH limitation */



































 503 int JLI_Open(const char* name, int flags) {
 504     int fd = _open(name, flags);
 505     if (fd == -1 && errno == ENOENT) {
 506         wchar_t* wname = NULL;
 507         wchar_t* wfullname = NULL;
 508         wchar_t* wfullname_w_prefix = NULL;
 509         size_t wnamelen, wfullnamelen, elplen;
 510         HANDLE h;
 511 
 512         wnamelen = strlen(name) + 1;
 513         wname = (wchar_t*) malloc(wnamelen*sizeof(wchar_t));
 514         if (wname == NULL) {
 515             goto end;
 516         }
 517         if (mbstowcs(wname, name, wnamelen - 1) == -1) {
 518             goto end;
 519         }
 520         wname[wnamelen - 1] = L'\0';
 521         wfullname = _wfullpath(wfullname, wname, 0);
 522         if (wfullname == NULL) {
 523             goto end;
 524         }
 525 
 526         wfullnamelen = wcslen(wfullname);
 527         if (wfullnamelen > 247) {
 528             elplen = wcslen(ELP_PREFIX);
 529             wfullname_w_prefix = (wchar_t*) malloc((elplen+wfullnamelen+1)*sizeof(wchar_t));
 530             wcscpy(wfullname_w_prefix, ELP_PREFIX);
 531             wcscpy(wfullname_w_prefix+elplen, wfullname);
 532 
 533             h = CreateFileW(wfullname_w_prefix, GENERIC_READ, FILE_SHARE_READ, NULL,
 534                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 535             if (h == INVALID_HANDLE_VALUE) {
 536                 goto end;
 537             }
 538             /* associates fd with handle */
 539             fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
 540         }
 541 end:
 542         free(wname);
 543         free(wfullname);
 544         free(wfullname_w_prefix);
 545     }
 546     return fd;
 547 }
 548 
 549 
 550 
 551 JNIEXPORT void JNICALL
 552 JLI_ReportErrorMessage(const char* fmt, ...) {
 553     va_list vl;
 554     va_start(vl,fmt);
 555 
 556     if (IsJavaw()) {
 557         char *message;
 558 
 559         /* get the length of the string we need */
 560         int n = _vscprintf(fmt, vl);
 561 
 562         message = (char *)JLI_MemAlloc(n + 1);
 563         _vsnprintf(message, n, fmt, vl);
 564         message[n]='\0';
 565         MessageBox(NULL, message, "Java Virtual Machine Launcher",
 566             (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
 567         JLI_MemFree(message);
 568     } else {
 569         vfprintf(stderr, fmt, vl);




  24  */
  25 
  26 #include <windows.h>
  27 #include <io.h>
  28 #include <process.h>
  29 #include <stdlib.h>
  30 #include <stdio.h>
  31 #include <stdarg.h>
  32 #include <string.h>
  33 #include <sys/types.h>
  34 #include <sys/stat.h>
  35 #include <wtypes.h>
  36 #include <commctrl.h>
  37 
  38 #include <jni.h>
  39 #include "java.h"
  40 
  41 #define JVM_DLL "jvm.dll"
  42 #define JAVA_DLL "java.dll"
  43 


  44 /*
  45  * Prototypes.
  46  */
  47 static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
  48                            char *jvmpath, jint jvmpathsize);
  49 static jboolean GetJREPath(char *path, jint pathsize);
  50 
  51 #ifdef USE_REGISTRY_LOOKUP
  52 jboolean GetPublicJREHome(char *buf, jint bufsize);
  53 #endif
  54 
  55 /* We supports warmup for UI stack that is performed in parallel
  56  * to VM initialization.
  57  * This helps to improve startup of UI application as warmup phase
  58  * might be long due to initialization of OS or hardware resources.
  59  * It is not CPU bound and therefore it does not interfere with VM init.
  60  * Obviously such warmup only has sense for UI apps and therefore it needs
  61  * to be explicitly requested by passing -Dsun.awt.warmup=true property
  62  * (this is always the case for plugin/javaws).
  63  *


 478     int rc;
 479     va_list vl;
 480     if (size == 0 || buffer == NULL)
 481         return -1;
 482     buffer[0] = '\0';
 483     va_start(vl, format);
 484     rc = vsnprintf(buffer, size, format, vl);
 485     va_end(vl);
 486     /* force a null terminator, if something is amiss */
 487     if (rc < 0) {
 488         /* apply ansi semantics */
 489         buffer[size - 1] = '\0';
 490         return (int)size;
 491     } else if (rc == size) {
 492         /* force a null terminator */
 493         buffer[size - 1] = '\0';
 494     }
 495     return rc;
 496 }
 497 
 498 /* taken from hotspot and slightly adjusted for jli lib; creates a UNC/ELP path from input 'path'
 499  * the return buffer is allocated in C heap and needs to be freed using JLI_MemFree by the caller.
 500  */
 501 static wchar_t* create_unc_path(const char* path, errno_t* err) {
 502     wchar_t* wpath = NULL;
 503     size_t converted_chars = 0;
 504     size_t path_len = strlen(path) + 1; /* includes the terminating NULL */
 505     if (path[0] == '\\' && path[1] == '\\') {
 506         if (path[2] == '?' && path[3] == '\\') {
 507             /* if it already has a \\?\ don't do the prefix */
 508             wpath = (wchar_t*) JLI_MemAlloc(path_len * sizeof(wchar_t));
 509             if (wpath != NULL) {
 510                 *err = mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
 511             } else {
 512                 *err = ENOMEM;
 513             }
 514         } else {
 515             /* only UNC pathname includes double slashes here */
 516             wpath = (wchar_t*) JLI_MemAlloc((path_len + 7) * sizeof(wchar_t));
 517             if (wpath != NULL) {
 518                 wcscpy(wpath, L"\\\\?\\UNC\0");
 519                 *err = mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
 520             } else {
 521                 *err = ENOMEM;
 522             }
 523         }
 524     } else {
 525         wpath = (wchar_t*) JLI_MemAlloc((path_len + 4) * sizeof(wchar_t));
 526         if (wpath != NULL) {
 527             wcscpy(wpath, L"\\\\?\\\0");
 528             *err = mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
 529         } else {
 530             *err = ENOMEM;
 531         }
 532     }
 533     return wpath;
 534 }
 535 
 536 int JLI_Open(const char* name, int flags) {
 537     int fd;
 538     if (strlen(name) < MAX_PATH) {
 539         fd = _open(name, flags);
 540     } else {
 541         errno_t err = ERROR_SUCCESS;
 542         wchar_t* wpath = create_unc_path(name, &err);
 543         if (err != ERROR_SUCCESS) {
 544             if (wpath != NULL) JLI_MemFree(wpath);
 545             errno = err;
 546             return -1;
 547         }
 548         fd = _wopen(wpath, flags);
 549         if (fd == -1) {
 550             errno = GetLastError();
 551         }
 552         JLI_MemFree(wpath);

























 553     }
 554     return fd;
 555 }


 556 
 557 JNIEXPORT void JNICALL
 558 JLI_ReportErrorMessage(const char* fmt, ...) {
 559     va_list vl;
 560     va_start(vl,fmt);
 561 
 562     if (IsJavaw()) {
 563         char *message;
 564 
 565         /* get the length of the string we need */
 566         int n = _vscprintf(fmt, vl);
 567 
 568         message = (char *)JLI_MemAlloc(n + 1);
 569         _vsnprintf(message, n, fmt, vl);
 570         message[n]='\0';
 571         MessageBox(NULL, message, "Java Virtual Machine Launcher",
 572             (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
 573         JLI_MemFree(message);
 574     } else {
 575         vfprintf(stderr, fmt, vl);


< prev index next >