8217093: Support extended-length paths in parse_manifest.c on windows
authormbaesken
Mon, 28 Jan 2019 16:42:23 +0100
changeset 53656 645ba889ee5f
parent 53655 c6e8196e4b54
child 53657 3954d70e1c50
8217093: Support extended-length paths in parse_manifest.c on windows Reviewed-by: chegar, clanger
src/java.base/share/native/libjli/jli_util.h
src/java.base/share/native/libjli/parse_manifest.c
src/java.base/windows/native/libjli/java_md.c
--- a/src/java.base/share/native/libjli/jli_util.h	Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/share/native/libjli/jli_util.h	Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -89,7 +89,8 @@
 #include <process.h>
 #define JLI_StrCaseCmp(p1, p2)          stricmp((p1), (p2))
 #define JLI_StrNCaseCmp(p1, p2, p3)     strnicmp((p1), (p2), (p3))
-int  JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
+int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
+int JLI_Open(const char* name, int flags);
 JNIEXPORT void JNICALL
 JLI_CmdToArgs(char *cmdline);
 #define JLI_Lseek                       _lseeki64
@@ -101,6 +102,7 @@
 #define JLI_StrCaseCmp(p1, p2)          strcasecmp((p1), (p2))
 #define JLI_StrNCaseCmp(p1, p2, p3)     strncasecmp((p1), (p2), (p3))
 #define JLI_Snprintf                    snprintf
+#define JLI_Open                        open
 #define JLI_PutEnv                      putenv
 #define JLI_GetPid                      getpid
 #ifdef __solaris__
--- a/src/java.base/share/native/libjli/parse_manifest.c	Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/share/native/libjli/parse_manifest.c	Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -362,9 +362,11 @@
     bp = buffer;
 
     if (find_positions(fd, bp, &base_offset, &censtart) == -1) {
+        free(buffer);
         return -1;
     }
     if (JLI_Lseek(fd, censtart, SEEK_SET) < (jlong) 0) {
+        free(buffer);
         return -1;
     }
 
@@ -583,7 +585,7 @@
     int     rc;
     char    *splashscreen_name = NULL;
 
-    if ((fd = open(jarfile, O_RDONLY
+    if ((fd = JLI_Open(jarfile, O_RDONLY
 #ifdef O_LARGEFILE
         | O_LARGEFILE /* large file mode */
 #endif
@@ -640,7 +642,7 @@
     zentry  entry;
     void    *data = NULL;
 
-    if ((fd = open(jarfile, O_RDONLY
+    if ((fd = JLI_Open(jarfile, O_RDONLY
 #ifdef O_LARGEFILE
         | O_LARGEFILE /* large file mode */
 #endif
@@ -688,7 +690,7 @@
     char    *value;
     int     rc;
 
-    if ((fd = open(jarfile, O_RDONLY
+    if ((fd = JLI_Open(jarfile, O_RDONLY
 #ifdef O_LARGEFILE
         | O_LARGEFILE /* large file mode */
 #endif
--- a/src/java.base/windows/native/libjli/java_md.c	Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/windows/native/libjli/java_md.c	Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,8 @@
 #define JVM_DLL "jvm.dll"
 #define JAVA_DLL "java.dll"
 
+#define ELP_PREFIX L"\\\\?\\"
+
 /*
  * Prototypes.
  */
@@ -495,6 +497,57 @@
     return rc;
 }
 
+/* On Windows, if _open fails, retry again with CreateFileW and
+ *  "\\?\" prefix ( extended-length paths) - this allows to open paths with larger file names;
+ * otherwise we run into the MAX_PATH limitation */
+int JLI_Open(const char* name, int flags) {
+    int fd = _open(name, flags);
+    if (fd == -1 && errno == ENOENT) {
+        wchar_t* wname = NULL;
+        wchar_t* wfullname = NULL;
+        wchar_t* wfullname_w_prefix = NULL;
+        size_t wnamelen, wfullnamelen, elplen;
+        HANDLE h;
+
+        wnamelen = strlen(name) + 1;
+        wname = (wchar_t*) malloc(wnamelen*sizeof(wchar_t));
+        if (wname == NULL) {
+            goto end;
+        }
+        if (mbstowcs(wname, name, wnamelen - 1) == -1) {
+            goto end;
+        }
+        wname[wnamelen - 1] = L'\0';
+        wfullname = _wfullpath(wfullname, wname, 0);
+        if (wfullname == NULL) {
+            goto end;
+        }
+
+        wfullnamelen = wcslen(wfullname);
+        if (wfullnamelen > 247) {
+            elplen = wcslen(ELP_PREFIX);
+            wfullname_w_prefix = (wchar_t*) malloc((elplen+wfullnamelen+1)*sizeof(wchar_t));
+            wcscpy(wfullname_w_prefix, ELP_PREFIX);
+            wcscpy(wfullname_w_prefix+elplen, wfullname);
+
+            h = CreateFileW(wfullname_w_prefix, GENERIC_READ, FILE_SHARE_READ, NULL,
+                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+            if (h == INVALID_HANDLE_VALUE) {
+                goto end;
+            }
+            /* associates fd with handle */
+            fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
+        }
+end:
+        free(wname);
+        free(wfullname);
+        free(wfullname_w_prefix);
+    }
+    return fd;
+}
+
+
+
 JNIEXPORT void JNICALL
 JLI_ReportErrorMessage(const char* fmt, ...) {
     va_list vl;