From 8bf4f5f2ef889f34d439adfd99802651e627db40 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 26 Jul 2012 21:24:39 +0200 Subject: [PATCH] Read root path attributes by IdeaWin32 --- bin/win/IdeaWin32.dll | Bin 35840 -> 35840 bytes bin/win/IdeaWin64.dll | Bin 41984 -> 41984 bytes native/IdeaWin32/IdeaWin32.cpp | 19 +++- .../openapi/vfs/local/FileWatcherTest.java | 41 +++----- .../openapi/util/io/win32/IdeaWin32.java | 21 +++- .../util/io/FileAttributesReadingTest.java | 95 +++++++++++++----- .../intellij/openapi/util/io/IoTestUtil.java | 46 ++++++++- 7 files changed, 158 insertions(+), 64 deletions(-) diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index 995f0ebc66c2757fec6c73ecd4b94f4dbbba0cc6..62fc0d58ab9b716090a7bde7199c3406ae31d259 100644 GIT binary patch delta 2838 zcmah~dsLNG7C#5?g)3g_8VD3m1x!@*yN~bv;%%ZLDi2LTQZyD1vxKyVUGj>dHw@-r z64Hc~OEkuvoaNaXlnnflGX+AP=nHFvGwIcNXQK6{_N&)(my zYV@gU^r_QEoZC3MzCQx5CL{4wp9UilaK^|9z6eo|ArxLeHk`bNS)ArYn}xP9FiqHa4p1%cIDuQ0r zs~TW7yHr%^m!~CrGQ(JmzatyM*Wp*m$cWEzIyn$A9lzkQM4tD-x5-fSQ}`rVI(9cG zg^ugPL*&-DariKaj+uj>_dFHz3dSuSpST~4_-9YwMBV^Wzp<@30`G?>Xirc9M;B zEUqRW(!rJ$ptr!)WzlDuD!X#E#pD=WARZjlbq)1_kD=`YO~_K6zOrJR>xD8@5w87w z5$Kg=)z>ObCDGcHb8y^!Ksy5`I!er%k(4tDki>0F2KFUCGVM5pyvI()Dml(Z;mhP2 z8w;rn<94JjJ*w*m;YhLNIb_ii2Eb#{4`6!uuE%LBD&G*hnow*%>BRNYp&RNLoq^0gSBCjnwQZY0^_ z&CsJq?l=!Bro7Hy*L2-At5?^$NwG8$pCCk>Hr90}xIZ3WoId8(hnJp|yIo95Nt__-Qgh@pjJR3Kw+vFzDuY z@DvBTd&h1Pu;f)vU5m!z#EQ7z{O^7LjET z@ZTNN$>e(ieuKo9N8w@5^zv4tHwfalD&E)vHQeo?SG{kHYk;i$UwDkq=>9mI7}tx= zqxS1|yJNj$v*WB|z!6Hz^hOE8KRjgS*TPbAEiZ zFki?Q9v8L=9-&p}6mAJtkriceuDD)o5%-FtBu;uq`at?r+AIA->Xg2gdZbfQuk@2N zC|#9qNk%z9eo!9glpmH8WL8d;XUKW-BDqX{QeG{um5JOW?~)J712R&~$`~a~8LK2H zc12QBlx52I$_3@Bf>fg#qK;L^tI6t2b%|Q8zNG$1ZBlotAFE%eH&n=AG(y=JApZ$3@4_j;oH}9R}K;4y2>#I68s0(<+@t&!rd9OXxCsGyN8Q zkRHk0&+v@Oq%jMbRm^KlAj`0c>>9R;J;a`2FR+8`71qG{J2?v%#U*eoCv)?-`CK8l zoGa&6anEv9Tn!|=fotY=aG!8{xK{29?n~}#uA4i~o#uYw5bw+1#|QFZd^A6SPv9MV z3jYY7$>;H_`L+BO{ww}l{wyCPLADmSkHW|+xl{f|J}>_w?^IjW4)vh=je1N)6hgz0-9### zT0(82j#C$?->7R;h&9}rWG%3MYJJ((VEe$G;yo<2dK|(J|<_;fSFp(F~nJ zXVBU7a(XT8cGC6qZn~8|Mr-sSeVz7arZ6j*cIE;zz{Ife>=agFlh|~22D^~m#MZHm z?0G21NG^t($W7%KPUNO@J2?-xk4xgS_(J}1{t5m(-^X9#Z}L$>EX1BDGzxzf-WKMI z`Qj5|t+-wMi}<$G1?6~B(j@04>9*u6o8@3RTplk^hPYKZL!K?qmzT)p^1E`od`9+F z1Jpn@OWm!aM1;Km$B3FuZKe9D53Ogc*|rrnr){q--R`nC+5PD-I_FLuJWIRiTKYTs zEPa{2ML)vKWAd4&nJR`bpD}|F9K*iDb~srx_Z-*6-4E|Lg-_%c@=N(rejUG!|BP?r z5Aa9$WBf(lU$6_Q!e*fXA~A~(h>>EBSS~J;o|K-K|0?@KS7a*-m8D9tQl_j_UQ_lf zXO%uhQwEeF<%%+_+=O1qfB>@9`RXFIT|KO7>aXe*by#)Y^tMSBLMvg4pr%pJP*v1= zs)l-*s-qgHMyi?mks6?es4LVkRb$<3U1%$`{Yqmdkcnehi0BFCMTlqz#B`83&0J!1 zW;7ea(rhNXm8GCapXFcY8Q}wAv=||75kG=2gCe6ss2%WUvYI`uHEAR2DZ_sNJqS05 delta 2686 zcmah~dstOf7T^2Ag{xlcs2~&%5kZSboO|!t=j`)F1OwxxB8dS}Nn<=lOEAqTkSnF% zO+&Y-`N(IbiDq6h$7sA0D4&RyLD@qCA2lZxvxkovA7}Q}na^+jnm>Mf@AX@2ueH}+ zYoAlU+ETyT(qshuR=_N~5CsJ?0H#>l3Wx+J3`hzBfPD&p$YmoV$#y6}i}y5434kSJ zh&3W%f(-yqM!P4+=We&pD4q+L{E3Dyn37Z4DYN9!qsP=FGiez=_n}Dea zSzy+$ptIergWBN7jj`UP5dws7l0%UVu#jX$wZaS%6rBZM_U1?TTHr0hj(h>0AX`SZ zz#cL+_8k0$sH0+G7bzPx5zhDS8TAH)W!|*-(^k0M85;DDu48LIt_4CQJ;k9hPsT-!s@4;x{n&?)Fa{axO4aSdP^$Iq&Xb-z*tY9fvEXDL0as_|;Ats=%q`GIct z95PPP9c>kMBZ%zclc7mY@)KY%86$iK)5&=u38s=TJOchs1RMvCkz)K#$nQbJ3GwEA;$& zXuKUX`f8ss_IrKe5(xW9t~?&TMc$NehWC7aCq&2$)*s?+!!+GFeWr1oY*!NCH>5|& zgA+-dngGj5p1K6CCa2VBXYU1ngbVTR>t=1tf*WQ2HVK|=JbjGPMh87~2N+H-@j{@x zypOhcpHWDXH5tB0p3^i~Mz(1<fYH26)g_BaK?D)fA|DaqsI(- zjB*vjOBb_71lgb`!ccNVZzOrC!{J8nvvh>x$;)F8K!&JkVNr3pfHC8i#N+{{iOyT8 z*u>GHjA9{qKJ6iDwIEqYCGOpa-obTtaeM@5%lVjr^4BbstRPggnKDs_fVJEl7#lU6~o&GQ#Gt(V$ zel-nTMyDARvnb|L)Ke^?XrkCc)~9EM-1Xl|<#vi53M1e9uk^7tSm{-Ak|5N`bGhT- zT(UEFI;@^JMC_^~&u`V*@^2@*W}VQU#}(6&y)8Y-vDW%6A4h{32bK2;7XN0o1tGj+;8lz!!!0@Oijm>Q`jsSZ_8RdupDO|4cJ ztIeuU?NYx|zgJJI{p#=PO*KG^*Vbs8wU0EPc2GN^oz{NREV^Bf)syu{^-20Py+WU* zFVOev?fQBBR~^IvkPiVE#13Uuc0YTR?PW(hG)Jc68Aqj~?s-R@!|U)lzH$UPM>%IY z*E`#t$DJpfH=KiA{jO`SKrW5TqPJ7bHF2xBE!=kQBkmKfo$KVfxnAx^uAlpzGdU|7 ziXu@gN!MO-8<6W5D9;wkZGF;+^H1gThRkQPaMXpwG9!{ll5bomYW zJ-P0n{ImRklBg6Ze^DBgRm#W8Nm`Pt$|EXP=cxA0cao!L8Fn19;-tWQ4N}pR-kQY7y1}=qD$xzzJcG&H}hxtpZQDtO&$tC!XP0+ zm>}c}Q-uw*9e)tc3g?AigsZ|0VF0ecv++C(MMjJf$A~H7263ynQ*0G`#d9=!AWfA@ zrRh?*93`j7Ir3BTpXBMvYqT9#E8CR1oyy;oLrRzOHO>1cKvtugv+{eVCFQ~>-x*ZbH)_I&!k5AMKgBD7K3Lt2u? zYDHR|wqDz+ZPS{y-CB#bPiv*GWuVUJA$qtTsW<3L^lkbFdW&ASPjA&v`LoIgU>2Q% zS&>a;)7eZmo6Tnn*r{wW`!3te?q*xqeQc&9*Ad~2aejdQj=Is0=o*URQ~0s`WWJn# zkzdTOrFk9TkJHj!;qMb37cL7vEQuxJRk7;Mp{K|*>9^swLIaiExk#^fQC7ge0UCPj AzyJUM diff --git a/bin/win/IdeaWin64.dll b/bin/win/IdeaWin64.dll index 9b8f2b13a79efb68fa942bcc69ff5b50bcbce5d0..4f67183261bafbec0b1e733051b9d14d7d651b40 100644 GIT binary patch delta 6778 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 diff --git a/native/IdeaWin32/IdeaWin32.cpp b/native/IdeaWin32/IdeaWin32.cpp index a408023ce251..f6648cc04978 100644 --- a/native/IdeaWin32/IdeaWin32.cpp +++ b/native/IdeaWin32/IdeaWin32.cpp @@ -142,15 +142,24 @@ JNIEXPORT void JNICALL Java_com_intellij_openapi_util_io_win32_IdeaWin32_initIDs 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); + bool isDrive = false; + if (env->GetStringLength(path) == 2) { + const jchar* str = env->GetStringChars(path, NULL); + isDrive = (str[1] == ':'); + env->ReleaseStringChars(path, str); + } - if (h == INVALID_HANDLE_VALUE) { - if (GetLastError() != ERROR_ACCESS_DENIED) { + WIN32_FIND_DATA data; + HANDLE h = INVALID_HANDLE_VALUE; + + if (!isDrive) { + h = FindFileInner(env, path, &data); + if (h == INVALID_HANDLE_VALUE && GetLastError() != ERROR_ACCESS_DENIED) { return NULL; } + } - // there is a chance that directory listing is denied but direct file access will succeed + if (h == INVALID_HANDLE_VALUE) { WIN32_FILE_ATTRIBUTE_DATA attrData; const jchar* str = env->GetStringChars(path, 0); BOOL res = GetFileAttributesEx((LPCWSTR)str, GetFileExInfoStandard, &attrData); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java index 91cbc04fb418..dbf34795b350 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/FileWatcherTest.java @@ -15,13 +15,13 @@ */ package com.intellij.openapi.vfs.local; -import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.IoTestUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.impl.local.FileWatcher; import com.intellij.openapi.vfs.newvfs.BulkFileListener; @@ -417,35 +417,16 @@ public class FileWatcherTest extends PlatformLangTestCase { return; } - final Set roots = ContainerUtil.map2Set(File.listRoots(), new Function() { - @Override - public Character fun(File root) { - return root.getPath().toLowerCase(Locale.US).charAt(0); - } - }); - char subst = 0; - for (char c = 'e'; c <= 'z'; c++) { - if (!roots.contains(c)) { - subst = c; - break; - } - } - assertFalse("Occupied: " + roots.toString(), subst == 0); - final File targetDir = FileUtil.createTempDirectory("top.", null); final File subDir = FileUtil.createTempDirectory(targetDir, "sub.", null); final File file = FileUtil.createTempFile(subDir, "test.", ".txt", true, false); - final int rv = new GeneralCommandLine("subst", subst + ":", targetDir.getAbsolutePath()).createProcess().waitFor(); - assertEquals(0, rv); - - final String substRoot = (subst + ":").toUpperCase(Locale.US); - VirtualDirectoryImpl.allowRootAccess(substRoot); - - final VirtualFile vfsRoot = myFileSystem.findFileByPath(substRoot); - assertNotNull(substRoot, vfsRoot); + final File rootFile = IoTestUtil.createSubst(targetDir.getAbsolutePath()); + VirtualDirectoryImpl.allowRootAccess(rootFile.getPath()); + final VirtualFile vfsRoot = myFileSystem.findFileByIoFile(rootFile); try { - final File substDir = new File(substRoot, subDir.getName()); + assertNotNull(rootFile.getPath(), vfsRoot); + final File substDir = new File(rootFile, subDir.getName()); final File substFile = new File(substDir, file.getName()); refresh(targetDir); refresh(substDir); @@ -476,10 +457,12 @@ public class FileWatcherTest extends PlatformLangTestCase { } finally { delete(targetDir); - new GeneralCommandLine("subst", subst + ":", "/d").createProcess().waitFor(); - ((NewVirtualFile)vfsRoot).markDirty(); - myFileSystem.refresh(false); - VirtualDirectoryImpl.disallowRootAccess(substRoot); + IoTestUtil.deleteSubst(rootFile.getPath()); + if (vfsRoot != null) { + ((NewVirtualFile)vfsRoot).markDirty(); + myFileSystem.refresh(false); + } + VirtualDirectoryImpl.disallowRootAccess(rootFile.getPath()); } } 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 575ae4f9f787..89a7b51fa01f 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 @@ -97,22 +97,33 @@ public class IdeaWin32 { @Nullable public FileInfo getInfo(@NotNull final String path) { - return getInfo0(unc(path)); + return getInfo0(path(path)); } @Nullable public String resolveSymLink(@NotNull final String path) { - final String result = resolveSymLink0(unc(path)); + final String result = resolveSymLink0(path(path)); return result != null && result.startsWith(PATH_PREFIX) ? result.substring(PREFIX_SIZE) : result; } @Nullable public FileInfo[] listChildren(@NotNull final String path) { - return listChildren0(unc(path) + PATH_SUFFIX); + return listChildren0(path(path) + PATH_SUFFIX); } - private static String unc(final String path) { - return path.length() < MAX_PATH ? path : PATH_PREFIX + path; + private static String path(final String path) { + final int length = path.length(); + if (length > 0 && path.charAt(length - 1) == '\\' || length >= MAX_PATH) { + final StringBuilder sb = new StringBuilder(path); + while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\\') { + sb.deleteCharAt(sb.length() - 1); + } + if (sb.length() >= MAX_PATH) { + sb.insert(0, PATH_PREFIX); + } + return sb.toString(); + } + return path; } private native FileInfo getInfo0(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 41bd996d02b1..53d1964d6563 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/FileAttributesReadingTest.java @@ -26,6 +26,7 @@ import org.junit.BeforeClass; import org.junit.Test; import java.io.File; +import java.util.Arrays; import static org.junit.Assert.*; import static org.junit.Assume.assumeTrue; @@ -67,12 +68,7 @@ public class FileAttributesReadingTest { final File file = FileUtil.createTempFile(myTempDirectory, "test.", ".txt", true); 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()); + assertFileAttributes(file); } @Test @@ -83,8 +79,34 @@ public class FileAttributesReadingTest { assertEquals(FileAttributes.Type.DIRECTORY, attributes.type); assertEquals(0, attributes.flags); assertEquals(file.length(), attributes.length); - assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); assertTrue(attributes.isWritable()); + if (SystemInfo.isWindows) { + assertDirectoriesEqual(file); + } + } + + @Test + public void root() throws Exception { + final File file = new File(SystemInfo.isWindows ? "C:\\" : "/"); + + final FileAttributes attributes = getAttributes(file); + assertEquals(FileAttributes.Type.DIRECTORY, attributes.type); + if (SystemInfo.isWindows) { + assertDirectoriesEqual(file); + } + } + + @Test + public void badNames() throws Exception { + final File file = FileUtil.createTempFile(myTempDirectory, "test.", ".txt", true); + FileUtil.writeToFile(file, myTestData); + + assertFileAttributes(new File(file.getPath() + StringUtil.repeat(File.separator, 3))); + assertFileAttributes(new File(file.getPath().replace(File.separator, StringUtil.repeat(File.separator, 3)))); + assertFileAttributes(new File(file.getPath().replace(File.separator, File.separator + "." + File.separator))); + assertFileAttributes(new File(myTempDirectory, + File.separator + ".." + File.separator + myTempDirectory.getName() + File.separator + file.getName())); } @Test @@ -113,7 +135,7 @@ public class FileAttributesReadingTest { assertEquals(FileAttributes.Type.FILE, attributes.type); assertEquals(FileAttributes.SYM_LINK, attributes.flags); assertEquals(myTestData.length, attributes.length); - assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); assertFalse(attributes.isWritable()); final String target = FileSystemUtil.resolveSymLink(link); @@ -135,7 +157,7 @@ public class FileAttributesReadingTest { assertEquals(FileAttributes.Type.FILE, attributes.type); assertEquals(FileAttributes.SYM_LINK, attributes.flags); assertEquals(myTestData.length, attributes.length); - assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); assertFalse(attributes.isWritable()); final String target = FileSystemUtil.resolveSymLink(link2); @@ -155,7 +177,7 @@ public class FileAttributesReadingTest { assertEquals(FileAttributes.Type.DIRECTORY, attributes.type); assertEquals(FileAttributes.SYM_LINK, attributes.flags); assertEquals(file.length(), attributes.length); - assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); if (SystemInfo.isUnix) assertFalse(attributes.isWritable()); final String target = FileSystemUtil.resolveSymLink(link); @@ -209,7 +231,7 @@ public class FileAttributesReadingTest { assertEquals(FileAttributes.Type.FILE, attributes.type); assertEquals(FileAttributes.HIDDEN, attributes.flags); assertEquals(file.length(), attributes.length); - assertTimestampEquals(file.lastModified(), attributes.lastModified); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); } @Test @@ -231,19 +253,25 @@ public class FileAttributesReadingTest { 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()); - + assertFileAttributes(file); 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); + assertDirectoriesEqual(dir); + } + } + + @Test + public void subst() throws Exception { + assumeTrue(SystemInfo.isWindows); + + FileUtil.createTempFile(myTempDirectory, "test.", ".txt", true); // just to populate a directory + final File substRoot = IoTestUtil.createSubst(myTempDirectory.getPath()); + try { + final FileAttributes attributes = getAttributes(substRoot); + assertEquals(FileAttributes.Type.DIRECTORY, attributes.type); + assertDirectoriesEqual(substRoot); + } + finally { + IoTestUtil.deleteSubst(substRoot.getPath()); } } @@ -255,10 +283,29 @@ public class FileAttributesReadingTest { return attributes; } - private static void assertTimestampEquals(final long expected, final long actual) { + private static void assertFileAttributes(@NotNull final File file) { + final FileAttributes attributes = getAttributes(file); + assertEquals(FileAttributes.Type.FILE, attributes.type); + assertEquals(0, attributes.flags); + assertEquals(file.length(), attributes.length); + assertTimestampsEqual(file.lastModified(), attributes.lastModified); + assertTrue(attributes.isWritable()); + } + + private static void assertTimestampsEqual(final long expected, final long actual) { final long roundedExpected = (expected / 1000) * 1000; final long roundedActual = (actual / 1000) * 1000; assertEquals("expected: " + expected + ", actual: " + actual, roundedExpected, roundedActual); } + + private static void assertDirectoriesEqual(@NotNull final File dir) { + final String[] list1 = dir.list(); + assertNotNull(list1); + final FileInfo[] list2 = IdeaWin32.getInstance().listChildren(dir.getPath()); + assertNotNull(list2); + if (list1.length + 2 != list2.length) { + assertEquals(Arrays.toString(list1), Arrays.toString(list2)); + } + } } diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java index 2a69a5489ff8..f88ad642e0a1 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java @@ -17,6 +17,8 @@ package com.intellij.openapi.util.io; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.io.BufferedReader; @@ -24,9 +26,10 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.util.Locale; +import java.util.Set; import static org.junit.Assert.*; -import static org.junit.Assert.assertEquals; public class IoTestUtil { private IoTestUtil() { } @@ -92,6 +95,47 @@ public class IoTestUtil { return junctionFile; } + public static File createSubst(@NotNull final String target) throws InterruptedException, IOException { + assertTrue(SystemInfo.isWindows); + + final File targetFile = new File(target); + assertTrue(targetFile.getPath(), targetFile.isDirectory()); + + final String substRoot = getFirstFreeDriveLetter() + ":"; + + final ProcessBuilder command = new ProcessBuilder("subst", substRoot, target); + final int res = runCommand(command); + assertEquals(command.command().toString(), 0, res); + + final File rootFile = new File(substRoot); + assertTrue("target=" + target + ", subst=" + rootFile, rootFile.isDirectory()); + return rootFile; + } + + public static void deleteSubst(@NotNull final String substRoot) throws InterruptedException, IOException { + runCommand(new ProcessBuilder("subst", substRoot, "/d")); + } + + private static char getFirstFreeDriveLetter() { + final Set roots = ContainerUtil.map2Set(File.listRoots(), new Function() { + @Override + public Character fun(File root) { + return root.getPath().toUpperCase(Locale.US).charAt(0); + } + }); + + char drive = 0; + for (char c = 'E'; c <= 'Z'; c++) { + if (!roots.contains(c)) { + drive = c; + break; + } + } + + assertFalse("Occupied: " + roots.toString(), drive == 0); + return drive; + } + private static File getFullLinkPath(final String link) { final boolean isAbsolute = SystemInfo.isUnix && StringUtil.startsWithChar(link, '/') || SystemInfo.isWindows && link.matches("^[c-zC-Z]:[/\\\\].*$");