jdk/src/windows/native/java/io/io_util_md.c
changeset 785 36c29b2692f1
parent 47 c8f0e41aea68
child 798 75b3a644ef91
equal deleted inserted replaced
784:b42ef9406aae 785:36c29b2692f1
   102         }
   102         }
   103         return curDirLenCached;
   103         return curDirLenCached;
   104     }
   104     }
   105 }
   105 }
   106 
   106 
       
   107 /*
       
   108   The "abpathlen" is the size of the buffer needed by _wfullpath. If the
       
   109   "path" is a relative path, it is "the length of the current dir" + "the
       
   110   length of the path", if it's "absolute" already, it's the same as
       
   111   pathlen which is the length of "path".
       
   112  */
       
   113 WCHAR* prefixAbpath(const WCHAR* path, int pathlen, int abpathlen) {
       
   114     WCHAR* pathbuf = NULL;
       
   115     WCHAR* abpath = NULL;
       
   116 
       
   117     abpathlen += 10;  //padding
       
   118     abpath = (WCHAR*)malloc(abpathlen * sizeof(WCHAR));
       
   119     if (abpath) {
       
   120         /* Collapse instances of "foo\.." and ensure absoluteness before
       
   121            going down to prefixing.
       
   122         */
       
   123         if (_wfullpath(abpath, path, abpathlen)) {
       
   124             pathbuf = getPrefixed(abpath, abpathlen);
       
   125         } else {
       
   126             /* _wfullpath fails if the pathlength exceeds 32k wchar.
       
   127                Instead of doing more fancy things we simply copy the
       
   128                ps into the return buffer, the subsequent win32 API will
       
   129                probably fail with FileNotFoundException, which is expected
       
   130             */
       
   131             pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
       
   132             if (pathbuf != 0) {
       
   133                 wcscpy(pathbuf, path);
       
   134             }
       
   135         }
       
   136         free(abpath);
       
   137     }
       
   138     return pathbuf;
       
   139 }
       
   140 
   107 /* If this returns NULL then an exception is pending */
   141 /* If this returns NULL then an exception is pending */
   108 WCHAR*
   142 WCHAR*
   109 pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
   143 pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
   110     int pathlen = 0;
   144     int pathlen = 0;
   111     WCHAR *pathbuf = NULL;
   145     WCHAR *pathbuf = NULL;
   112     int max_path = 248;   /* Since CreateDirectoryW() has the limit of
   146     int max_path = 248; /* CreateDirectoryW() has the limit of 248 */
   113                              248 instead of the normal MAX_PATH, we
   147 
   114                              use 248 as the max_path to satisfy both
       
   115                            */
       
   116     WITH_UNICODE_STRING(env, path, ps) {
   148     WITH_UNICODE_STRING(env, path, ps) {
   117         pathlen = wcslen(ps);
   149         pathlen = wcslen(ps);
   118         if (pathlen != 0) {
   150         if (pathlen != 0) {
   119             if (pathlen > 2 &&
   151             if (pathlen > 2 &&
   120                 (ps[0] == L'\\' && ps[1] == L'\\' ||   //UNC
   152                 (ps[0] == L'\\' && ps[1] == L'\\' ||   //UNC
   121                  ps[1] == L':' && ps[2] == L'\\')) {   //absolute
   153                  ps[1] == L':' && ps[2] == L'\\'))     //absolute
       
   154             {
   122                  if (pathlen > max_path - 1) {
   155                  if (pathlen > max_path - 1) {
   123                      pathbuf = getPrefixed(ps, pathlen);
   156                      pathbuf = prefixAbpath(ps, pathlen, pathlen);
   124                  } else {
   157                  } else {
   125                      pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
   158                      pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
   126                      if (pathbuf != 0) {
   159                      if (pathbuf != 0) {
   127                          wcscpy(pathbuf, ps);
   160                          wcscpy(pathbuf, ps);
   128                      }
   161                      }
   130             } else {
   163             } else {
   131                 /* If the path came in as a relative path, need to verify if
   164                 /* If the path came in as a relative path, need to verify if
   132                    its absolute form is bigger than max_path or not, if yes
   165                    its absolute form is bigger than max_path or not, if yes
   133                    need to (1)convert it to absolute and (2)prefix. This is
   166                    need to (1)convert it to absolute and (2)prefix. This is
   134                    obviously a burden to all relative paths (The current dir/len
   167                    obviously a burden to all relative paths (The current dir/len
   135                    for "dirve & directory" relative path is cached, so we only
   168                    for "drive & directory" relative path is cached, so we only
   136                    calculate it once but for "drive-relative path we call
   169                    calculate it once but for "drive-relative path we call
   137                    _wgetdcwd() and wcslen() everytime), but a hit we have
   170                    _wgetdcwd() and wcslen() everytime), but a hit we have
   138                    to take if we want to support relative path beyond max_path.
   171                    to take if we want to support relative path beyond max_path.
   139                    There is no way to predict how long the absolute path will be
   172                    There is no way to predict how long the absolute path will be
   140                    (therefor allocate the sufficient memory block) before calling
   173                    (therefor allocate the sufficient memory block) before calling
   141                    _wfullpath(), we have to get the length of "current" dir first.
   174                    _wfullpath(), we have to get the length of "current" dir first.
   142                 */
   175                 */
   143                 WCHAR *abpath = NULL;
   176                 WCHAR *abpath = NULL;
   144                 int dirlen = currentDirLength(ps, pathlen);
   177                 int dirlen = currentDirLength(ps, pathlen);
   145                 if (dirlen + pathlen + 1 > max_path - 1) {
   178                 if (dirlen + pathlen + 1 > max_path - 1) {
   146                     int abpathlen = dirlen + pathlen + 10;
   179                     pathbuf = prefixAbpath(ps, pathlen, dirlen + pathlen);
   147                     abpath = (WCHAR*)malloc(abpathlen * sizeof(WCHAR));
       
   148                     if (abpath) {
       
   149                         if (_wfullpath(abpath, ps, abpathlen)) {
       
   150                             pathbuf = getPrefixed(abpath, abpathlen);
       
   151                         } else {
       
   152                             /* _wfullpath fails if the pathlength exceeds 32k wchar.
       
   153                                Instead of doing more fancy things we simply copy the
       
   154                                ps into the return buffer, the subsequent win32 API will
       
   155                                probably fail with FileNotFoundException, which is expected
       
   156                              */
       
   157                             pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
       
   158                             if (pathbuf != 0) {
       
   159                                 wcscpy(pathbuf, ps);
       
   160                             }
       
   161                         }
       
   162                         free(abpath);
       
   163                     }
       
   164                 } else {
   180                 } else {
   165                     pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
   181                     pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
   166                     if (pathbuf != 0) {
   182                     if (pathbuf != 0) {
   167                         wcscpy(pathbuf, ps);
   183                         wcscpy(pathbuf, ps);
   168                     }
   184                     }