From b6ac7c8947cd6168b5b125c931036aa73de8a76b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 25 Jul 2012 19:28:23 +0200 Subject: [PATCH] Handle long file names by IdeaWin32 --- bin/win/IdeaWin32.dll | Bin 35840 -> 35840 bytes bin/win/IdeaWin64.dll | Bin 41472 -> 41472 bytes native/IdeaWin32/IdeaWin32.cpp | 6 +-- native/IdeaWin32/IdeaWin32.h | 6 +-- .../openapi/vfs/impl/win32/Win32FsCache.java | 11 +++-- .../openapi/util/io/FileSystemUtil.java | 6 +-- .../openapi/util/io/win32/IdeaWin32.java | 32 +++++++++++++-- .../util/io/FileAttributesReadingTest.java | 38 ++++++++++++++++++ 8 files changed, 79 insertions(+), 20 deletions(-) diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index a7560a1edc3fb90bb5e73cb54162d489a60d8054..3256217b082d27d90654e929067df7309d5fd0ee 100644 GIT binary patch delta 124 zcmZpe!PGE=X~GYtB+ZGx{Fu&5PWEC{VoaHw%ea~`WV0lbbRbY>vsv&yae)H?`F*Kh zm7Hfji#-_?A=0p!CHn(AQ=;bNZ$)ODy^RbEr+}DmvT1QJi-Cio(PZCZlgaywJrNxH Q5vsv&yae>UsNveLw z#XT2JTvm3X{BrhYmh2DgK-tOPip)5B8W|W)0x{2I)8b%e2ScODzQrb!4-|V&<|=XB O98j`>ar56&W-$OY#wsTO diff --git a/bin/win/IdeaWin64.dll b/bin/win/IdeaWin64.dll index 1b40f5f3dcc48520414f385a4c26978b73d2435b..82abbb1c3e65a918b753cee50682046795da9cff 100644 GIT binary patch delta 125 zcmZoT!qjktX~GAl(;5>$`7t>aOm<>4Vho*J%D9@*bh9Fpa|}>sb6VUd34t{ocVE3- zq31i%el0_H*Tut|Gssb6VUd34w=m(xSOP zad=IZ5PLFhQ=if1jPe>@pzP#lEoPh*GZ`2*0rAJls;xnjZCi~euWoe%(R@Xz#rZj9 Zslk=GKACyhn;qNsGfqChD6ptQ3IJWiFL?j} 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);