/* If this returns NULL then an exception is pending */ WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) { int pathlen = 0; WCHAR *pathbuf = NULL; int max_path = 248; /* CreateDirectoryW() has the limit of 248 */ WITH_UNICODE_STRING(env, path, ps) { pathlen = (int)wcslen(ps); if (pathlen != 0) { if (pathlen > 2 && (ps[0] == L'\\' && ps[1] == L'\\' || //UNC ps[1] == L':' && ps[2] == L'\\')) //absolute { if (pathlen > max_path - 1) { pathbuf = prefixAbpath(ps, pathlen, pathlen); } else { pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR)); if (pathbuf != 0) { wcscpy(pathbuf, ps); } } } else { /* If the path came in as a relative path, need to verify if its absolute form is bigger than max_path or not, if yes need to (1)convert it to absolute and (2)prefix. This is obviously a burden to all relative paths (The current dir/len for "drive & directory" relative path is cached, so we only calculate it once but for "drive-relative path we call _wgetdcwd() and wcslen() everytime), but a hit we have to take if we want to support relative path beyond max_path. There is no way to predict how long the absolute path will be (therefor allocate the sufficient memory block) before calling _wfullpath(), we have to get the length of "current" dir first. */ WCHAR *abpath = NULL; int dirlen = currentDirLength(ps, pathlen); if (dirlen + pathlen + 1 > max_path - 1) { pathbuf = prefixAbpath(ps, pathlen, dirlen + pathlen); } else { pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR)); if (pathbuf != 0) { wcscpy(pathbuf, ps); } } } } } END_UNICODE_STRING(env, ps);
WITH_UNICODE_STRING(env, pathname, path) { /*we estimate the max length of memory needed as "currentDir. length + pathname.length" */ int len = wcslen(path); len += currentDirLength(path, len); if (len > MAX_PATH_LENGTH - 1) { WCHAR *cp = (WCHAR*)malloc(len * sizeof(WCHAR)); if (cp != NULL) { if (wcanonicalize(path, cp, len) >= 0) { rv = (*env)->NewString(env, cp, wcslen(cp)); } free(cp); } } else if (wcanonicalize(path, canonicalPath, MAX_PATH_LENGTH) >= 0) { rv = (*env)->NewString(env, canonicalPath, wcslen(canonicalPath)); } } END_UNICODE_STRING(env, path);