diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index a7560a1edc3f..3256217b082d 100644 Binary files a/bin/win/IdeaWin32.dll and b/bin/win/IdeaWin32.dll differ diff --git a/bin/win/IdeaWin64.dll b/bin/win/IdeaWin64.dll index 1b40f5f3dcc4..82abbb1c3e65 100644 Binary files a/bin/win/IdeaWin64.dll and b/bin/win/IdeaWin64.dll differ diff --git a/native/IdeaWin32/IdeaWin32.cpp b/native/IdeaWin32/IdeaWin32.cpp index 2f1fd11f4370..b433870f05d4 100644 --- a/native/IdeaWin32/IdeaWin32.cpp +++ b/native/IdeaWin32/IdeaWin32.cpp @@ -128,7 +128,7 @@ JNIEXPORT void JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_initIDs } -JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) { +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo0(JNIEnv *env, jobject method, jstring path) { WIN32_FIND_DATA data; HANDLE h = FindFileInner(env, path, &data); @@ -165,7 +165,7 @@ JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getI } -JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink(JNIEnv *env, jobject method, jstring path) { +JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink0(JNIEnv *env, jobject method, jstring path) { WIN32_FIND_DATA data; HANDLE h = FindFileInner(env, path, &data); if (h == INVALID_HANDLE_VALUE) { @@ -209,7 +209,7 @@ JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_reso } -JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path) { +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren0(JNIEnv *env, jobject method, jstring path) { WIN32_FIND_DATA data; HANDLE h = FindFileInner(env, path, &data); if (h == INVALID_HANDLE_VALUE) { diff --git a/native/IdeaWin32/IdeaWin32.h b/native/IdeaWin32/IdeaWin32.h index 67173207e1f1..3f69378aef36 100644 --- a/native/IdeaWin32/IdeaWin32.h +++ b/native/IdeaWin32/IdeaWin32.h @@ -25,13 +25,13 @@ extern "C" { JNIEXPORT void JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_initIDs (JNIEnv *, jclass); -JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_getInfo0 (JNIEnv *, jobject, jstring); -JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink +JNIEXPORT jstring JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_resolveSymLink0 (JNIEnv *, jobject, jstring); -JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_listChildren0 (JNIEnv *, jobject, jstring); #ifdef __cplusplus diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32FsCache.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32FsCache.java index 0f134d6d2b98..e5e16133a219 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32FsCache.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32FsCache.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.vfs.impl.win32; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.win32.FileInfo; import com.intellij.openapi.util.io.win32.IdeaWin32; @@ -32,7 +31,7 @@ import java.util.Map; * @author Dmitry Avdeev */ class Win32FsCache { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32FsCache"); + //private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32FsCache"); private final IdeaWin32 myKernel = IdeaWin32.getInstance(); private final Map myCache = new THashMap(); @@ -43,13 +42,13 @@ class Win32FsCache { @NotNull String[] list(@NotNull String absolutePath) { - FileInfo[] fileInfos = myKernel.listChildren(absolutePath.replace('/', '\\') + "\\*.*"); - if (fileInfos == null) { + FileInfo[] fileInfo = myKernel.listChildren(absolutePath.replace('/', '\\')); + if (fileInfo == null) { return ArrayUtil.EMPTY_STRING_ARRAY; } - ArrayList names = new ArrayList(fileInfos.length); - for (FileInfo info : fileInfos) { + ArrayList names = new ArrayList(fileInfo.length); + for (FileInfo info : fileInfo) { if (info.name.equals(".")) { myCache.put(absolutePath, info); continue; diff --git a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java index 118bbe361320..337119cc0fa2 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java @@ -351,9 +351,6 @@ public class FileSystemUtil { private static class IdeaWin32MediatorImpl implements Mediator { - private static final String PATH_PREFIX = "\\\\?\\"; - private static final int PREFIX_SIZE = PATH_PREFIX.length(); - private IdeaWin32 myInstance = IdeaWin32.getInstance(); @Override @@ -373,8 +370,7 @@ public class FileSystemUtil { @Override public String resolveSymLink(@NotNull final String path) throws Exception { - final String result = myInstance.resolveSymLink(path); - return result != null && result.startsWith(PATH_PREFIX) ? result.substring(PREFIX_SIZE) : result; + return myInstance.resolveSymLink(path); } @Override diff --git a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java index 2e81a993d365..1ebf61203d84 100644 --- a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java +++ b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java @@ -19,6 +19,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Do not use this class directly. @@ -29,6 +30,11 @@ import org.jetbrains.annotations.NotNull; public class IdeaWin32 { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.win32.Win32LocalFileSystem"); + private static final String PATH_PREFIX = "\\\\?\\"; + private static final int PREFIX_SIZE = PATH_PREFIX.length(); + private static final String PATH_SUFFIX = "\\*.*"; + private static final int MAX_PATH = 260; + private static final IdeaWin32 ourInstance; static { @@ -87,9 +93,29 @@ public class IdeaWin32 { private static native void initIDs(); - public native FileInfo getInfo(String path); + @Nullable + public FileInfo getInfo(@NotNull final String path) { + return getInfo0(unc(path)); + } - public native String resolveSymLink(String path); + @Nullable + public String resolveSymLink(@NotNull final String path) { + final String result = resolveSymLink0(unc(path)); + return result != null && result.startsWith(PATH_PREFIX) ? result.substring(PREFIX_SIZE) : result; + } - public native FileInfo[] listChildren(String path); + @Nullable + public FileInfo[] listChildren(@NotNull final String path) { + return listChildren0(unc(path) + PATH_SUFFIX); + } + + private static String unc(final String path) { + return path.length() < MAX_PATH ? path : PATH_PREFIX + path; + } + + private native FileInfo getInfo0(String path); + + private native String resolveSymLink0(String path); + + private native FileInfo[] listChildren0(String path); } diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java index de15b3f70060..0ac50050a0d1 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java @@ -16,6 +16,9 @@ package com.intellij.openapi.util.io; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.win32.FileInfo; +import com.intellij.openapi.util.io.win32.IdeaWin32; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Before; @@ -201,6 +204,41 @@ public class FileAttributesReadingTest { assertTimestampEquals(file.lastModified(), attributes.lastModified); } + @Test + public void extraLongName() throws Exception { + final String prefix = StringUtil.repeatSymbol('a', 128) + "."; + final File dir = FileUtil.createTempDirectory( + FileUtil.createTempDirectory( + FileUtil.createTempDirectory( + FileUtil.createTempDirectory( + FileUtil.createTempDirectory( + FileUtil.createTempDirectory( + myTempDirectory, prefix, ".dir"), + prefix, ".dir"), + prefix, ".dir"), + prefix, ".dir"), + prefix, ".dir"), + prefix, ".dir"); + final File file = FileUtil.createTempFile(dir, prefix, ".txt", true); + assertTrue(file.exists()); + FileUtil.writeToFile(file, myTestData); + + final FileAttributes attributes = getAttributes(file); + assertEquals(FileAttributes.Type.FILE, attributes.type); + assertEquals(0, attributes.flags); + assertEquals(myTestData.length, attributes.length); + assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTrue(attributes.isWritable()); + + if (SystemInfo.isWindows) { + final String[] list1 = dir.list(); + assertNotNull(list1); + final FileInfo[] list2 = IdeaWin32.getInstance().listChildren(dir.getPath()); + assertNotNull(list2); + assertEquals(list1.length + 2, list2.length); + } + } + @NotNull private static FileAttributes getAttributes(@NotNull final File file) { final FileAttributes attributes = FileSystemUtil.getAttributes(file);