Skip to content
This repository has been archived by the owner on Dec 6, 2024. It is now read-only.

Commit

Permalink
Another fix for #288: Directory \\?\c:\ does not exists
Browse files Browse the repository at this point in the history
  • Loading branch information
Yomodo committed Mar 12, 2018
1 parent f85e5ba commit a00430b
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ private void Directory_Exists_DriveLetter(bool isNetwork)
var inputDrive = driveSysIO;
var existSysIO = System.IO.Directory.Exists(inputDrive);
var existAlpha = Alphaleonis.Win32.Filesystem.Directory.Exists(inputDrive);

Console.WriteLine("\nSystem.IO/AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);

Assert.AreEqual(sysIOshouldBe, existSysIO, "The result should be: " + sysIOshouldBe.ToString().ToUpperInvariant());
Expand All @@ -57,12 +58,14 @@ private void Directory_Exists_DriveLetter(bool isNetwork)



//C:\
// C:\
sysIOshouldBe = true;
inputDrive = driveSysIO + @"\";
existSysIO = System.IO.Directory.Exists(inputDrive);
existAlpha = Alphaleonis.Win32.Filesystem.Directory.Exists(inputDrive);
Console.WriteLine("System.IO/AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);

Console.WriteLine("\nSystem.IO (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);
Console.WriteLine("AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", true.ToString().ToUpperInvariant(), existAlpha, inputDrive);

Assert.AreEqual(sysIOshouldBe, existSysIO, "The result should be: " + sysIOshouldBe.ToString().ToUpperInvariant());
Assert.AreEqual(existSysIO, existAlpha, "The results are not equal, but are expected to be.");
Expand All @@ -75,8 +78,9 @@ private void Directory_Exists_DriveLetter(bool isNetwork)
inputDrive = isNetwork ? Alphaleonis.Win32.Filesystem.Path.LongPathUncPrefix + driveSysIO.TrimStart('\\') : Alphaleonis.Win32.Filesystem.Path.LongPathPrefix + driveSysIO;
existSysIO = System.IO.Directory.Exists(inputDrive);
existAlpha = Alphaleonis.Win32.Filesystem.Directory.Exists(inputDrive);
Console.WriteLine("\nSystem.IO (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);
Console.WriteLine("AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", true.ToString().ToUpperInvariant(), existAlpha, inputDrive);

Console.WriteLine("\nSystem.IO (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);
Console.WriteLine("AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", true.ToString().ToUpperInvariant(), existAlpha, inputDrive);

Assert.AreEqual(sysIOshouldBe, existSysIO, "The result should be: " + sysIOshouldBe.ToString().ToUpperInvariant());
Assert.IsTrue(existAlpha);
Expand All @@ -89,15 +93,12 @@ private void Directory_Exists_DriveLetter(bool isNetwork)
inputDrive = (isNetwork ? Alphaleonis.Win32.Filesystem.Path.LongPathUncPrefix + driveSysIO.TrimStart('\\') : Alphaleonis.Win32.Filesystem.Path.LongPathPrefix + driveSysIO) + @"\";
existSysIO = System.IO.Directory.Exists(inputDrive);
existAlpha = Alphaleonis.Win32.Filesystem.Directory.Exists(inputDrive);
Console.WriteLine("\nSystem.IO (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);
Console.WriteLine("AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", true.ToString().ToUpperInvariant(), existAlpha, inputDrive);

if (!isNetwork)
Console.WriteLine("BUG: AlphaFS should return TRUE.");


Console.WriteLine("\nSystem.IO (should be {0}):\t[{1}]\t\tdrive= {2}", sysIOshouldBe.ToString().ToUpperInvariant(), existSysIO, inputDrive);
Console.WriteLine("AlphaFS (should be {0}):\t[{1}]\t\tdrive= {2}", true.ToString().ToUpperInvariant(), existAlpha, inputDrive);

Assert.AreEqual(sysIOshouldBe, existSysIO, "The result should be: " + sysIOshouldBe.ToString().ToUpperInvariant());
Assert.AreEqual(isNetwork, existAlpha);
Assert.IsTrue(existAlpha);


Console.WriteLine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,15 @@ private void Directory_Exists_UseCases(bool isNetwork)
Console.WriteLine();


var sysDrive = UnitTestConstants.SysDrive + @"\";

var tempPath = System.IO.Path.GetTempPath();

if (isNetwork)
{
sysDrive = Alphaleonis.Win32.Filesystem.Path.LocalToUnc(sysDrive);
tempPath = Alphaleonis.Win32.Filesystem.Path.LocalToUnc(tempPath);
}


using (new TemporaryDirectory(tempPath, MethodBase.GetCurrentMethod().Name))
Expand Down Expand Up @@ -97,7 +103,7 @@ private void Directory_Exists_UseCases(bool isNetwork)

try
{
System.IO.Directory.SetCurrentDirectory(UnitTestConstants.SysDrive + @"\");
System.IO.Directory.SetCurrentDirectory(sysDrive);

Console.WriteLine("Current directory: " + System.IO.Directory.GetCurrentDirectory());

Expand Down
7 changes: 4 additions & 3 deletions AlphaFS/Filesystem/File Class/File.Exists.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ internal static bool ExistsCore(KernelTransaction transaction, bool isFolder, st
// Check for driveletter, such as: "C:"
var pathRp = Path.GetRegularPathCore(path, GetFullPathOptions.None, false);

if (pathRp.Length == 2 && Path.IsPathRooted(pathRp, false))
if (pathRp.Length == 2 && Path.IsLogicalDriveCore(pathRp, true, PathFormat.LongFullPath))
path = pathRp;


Expand All @@ -210,11 +210,12 @@ internal static bool ExistsCore(KernelTransaction transaction, bool isFolder, st

var dataInitialised = FillAttributeInfoCore(transaction, pathLp, ref attrs, false, true);

if (dataInitialised == Win32Errors.ERROR_INVALID_NAME)
if (dataInitialised == Win32Errors.ERROR_INVALID_NAME || dataInitialised == Win32Errors.ERROR_INVALID_PARAMETER)
{
// Issue #288: Directory.Exists on root drive problem has come back with recent updates
//
// A relative path with a long path prefix: FindFirstFileEx("\\\\?\\C:qr4bxbzb.k1v-exists", ...
// ERROR_INVALID_NAME : A relative path with a long path prefix: FindFirstFileEx("\\\\?\\C:qr4bxbzb.k1v-exists", ...
// ERROR_INVALID_PARAMETER: A drive path with a long path prefix : GetFileAttributesTransacted("\\?\C:\", ...


dataInitialised = FillAttributeInfoCore(transaction, pathRp, ref attrs, false, true);
Expand Down
17 changes: 1 addition & 16 deletions AlphaFS/Filesystem/File Class/File.GetAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ internal static T GetAttributesExCore<T>(KernelTransaction transaction, string p
if (dataInitialised != Win32Errors.ERROR_SUCCESS)
NativeError.ThrowException(dataInitialised, pathLp);

return (T)(typeof(T) == typeof(FileAttributes) ? (object)data.dwFileAttributes : data);
return (T) (typeof(T) == typeof(FileAttributes) ? (object) data.dwFileAttributes : data);
}

/// <summary>
Expand Down Expand Up @@ -135,12 +135,6 @@ internal static int FillAttributeInfoCore(KernelTransaction transaction, string
switch ((uint) lastError)
{
case Win32Errors.ERROR_INVALID_NAME:

// Issue #288: Directory.Exists on root drive problem has come back with recent updates
//
// A relative path with a long path prefix: FindFirstFileEx("\\\\?\\C:qr4bxbzb.k1v-exists", ...


case Win32Errors.ERROR_FILE_NOT_FOUND: // On files.
case Win32Errors.ERROR_PATH_NOT_FOUND: // On folders.
case Win32Errors.ERROR_NOT_READY: // DeviceNotReadyException: Floppy device or network drive not ready.
Expand Down Expand Up @@ -186,15 +180,6 @@ internal static int FillAttributeInfoCore(KernelTransaction transaction, string
case Win32Errors.ERROR_PATH_NOT_FOUND: // On folders.
case Win32Errors.ERROR_NOT_READY: // DeviceNotReadyException: Floppy device or network drive not ready.

// Issue #288: Directory.Exists on root drive problem has come back with recent updates
//
// It seems that GetFileAttributesEx cannot handle a relative path with a long path prefix.
//
// Returns false: NativeMethods.GetFileAttributesEx("\\\\?\\C:qr4bxbzb.k1v-exists", ...
// Returns true : NativeMethods.GetFileAttributesEx("\\\\?\\C:\\qr4bxbzb.k1v-exists", ...
// Returns true : NativeMethods.GetFileAttributesEx("C:qr4bxbzb.k1v-exists", ...


// In case someone latched onto the file. Take the perf hit only for failure.
return FillAttributeInfoCore(transaction, pathLp, ref win32AttrData, true, returnErrorOnNotFound);
}
Expand Down
16 changes: 11 additions & 5 deletions AlphaFS/Filesystem/Path Class/Path.IsLogicalDrive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static partial class Path
/// <param name="path">The absolute path to check.</param>
public static bool IsLogicalDrive(string path)
{
return IsLogicalDriveCore(path, PathFormat.FullPath);
return IsLogicalDriveCore(path, false, PathFormat.FullPath);
}


Expand All @@ -41,8 +41,9 @@ public static bool IsLogicalDrive(string path)
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <param name="path">The absolute path to check.</param>
/// <param name="isRegularPath"><see langword="true"/> indicates the path is already a regular path.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
internal static bool IsLogicalDriveCore(string path, PathFormat pathFormat)
internal static bool IsLogicalDriveCore(string path, bool isRegularPath, PathFormat pathFormat)
{
if (pathFormat != PathFormat.LongFullPath)
{
Expand All @@ -53,11 +54,16 @@ internal static bool IsLogicalDriveCore(string path, PathFormat pathFormat)
}


// Don't use char.IsLetter() here as that can be misleading; The only valid drive letters are: A-Z.
if (!isRegularPath)
path = GetRegularPathCore(path, GetFullPathOptions.None, false);

var regularPath = path.StartsWith(LogicalDrivePrefix, StringComparison.OrdinalIgnoreCase) ? path.Substring(LogicalDrivePrefix.Length) : path;

var c = regularPath.ToUpperInvariant()[0];

var c = path.ToUpperInvariant()[0];
// Don't use char.IsLetter() here as that can be misleading; The only valid drive letters are: A-Z.

return path[1] == VolumeSeparatorChar && c >= 'A' && c <= 'Z';
return regularPath[1] == VolumeSeparatorChar && c >= 'A' && c <= 'Z';
}
}
}
2 changes: 1 addition & 1 deletion AlphaFS/Filesystem/Path Class/Path.ShortLongConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ internal static string GetLongPathCore(string path, GetFullPathOptions options)
return LongPathUncPrefix + path.Substring(UncPrefix.Length);


return IsPathRooted(path, false) && IsLogicalDriveCore(path, PathFormat.LongFullPath) ? LongPathPrefix + path : path;
return IsPathRooted(path, false) && IsLogicalDriveCore(path, false, PathFormat.LongFullPath) ? LongPathPrefix + path : path;
}


Expand Down

0 comments on commit a00430b

Please sign in to comment.