Fix FileSystemProvider to work with volume and pipe paths (#15873)

This commit is contained in:
Steve Lee
2022-07-25 22:07:26 +00:00
committed by GitHub
parent 1a8d23f578
commit d72cedd70b
3 changed files with 24 additions and 11 deletions
@@ -1281,7 +1281,7 @@ namespace System.Management.Automation
return false;
}
internal static bool PathIsUnc(string path)
internal static bool PathIsUnc(string path, bool networkOnly = false)
{
#if UNIX
return false;
@@ -1291,8 +1291,8 @@ namespace System.Management.Automation
return false;
}
// handle special cases like \\wsl$\ubuntu which isn't a UNC path, but we can say it is so the filesystemprovider can use it
if (path.StartsWith(WslRootPath, StringComparison.OrdinalIgnoreCase))
// handle special cases like '\\wsl$\ubuntu', '\\?\', and '\\.\pipe\' which aren't a UNC path, but we can say it is so the filesystemprovider can use it
if (!networkOnly && (path.StartsWith(WslRootPath, StringComparison.OrdinalIgnoreCase) || path.StartsWith("\\\\?\\") || path.StartsWith("\\\\.\\")))
{
return true;
}
@@ -132,20 +132,21 @@ namespace Microsoft.PowerShell.Commands
itemsToSkip = 4;
}
foreach (string item in path.Split(StringLiterals.DefaultPathSeparator))
var items = path.Split(StringLiterals.DefaultPathSeparator);
for (int i = 0; i < items.Length; i++)
{
if (itemsToSkip-- > 0)
{
// This handles the UNC server and share and 8.3 short path syntax
exactPath += item + StringLiterals.DefaultPathSeparator;
exactPath += items[i] + StringLiterals.DefaultPathSeparator;
continue;
}
else if (string.IsNullOrEmpty(exactPath))
{
// This handles the drive letter or / root path start
exactPath = item + StringLiterals.DefaultPathSeparator;
exactPath = items[i] + StringLiterals.DefaultPathSeparator;
}
else if (string.IsNullOrEmpty(item))
else if (string.IsNullOrEmpty(items[i]) && i == items.Length - 1)
{
// This handles the trailing slash case
if (!exactPath.EndsWith(StringLiterals.DefaultPathSeparator))
@@ -155,17 +156,17 @@ namespace Microsoft.PowerShell.Commands
break;
}
else if (item.Contains('~'))
else if (items[i].Contains('~'))
{
// This handles short path names
exactPath += StringLiterals.DefaultPathSeparator + item;
exactPath += StringLiterals.DefaultPathSeparator + items[i];
}
else
{
// Use GetFileSystemEntries to get the correct casing of this element
try
{
var entries = Directory.GetFileSystemEntries(exactPath, item);
var entries = Directory.GetFileSystemEntries(exactPath, items[i]);
if (entries.Length > 0)
{
exactPath = entries[0];
@@ -7257,7 +7258,7 @@ namespace Microsoft.PowerShell.Commands
return false;
}
if (Utils.PathIsUnc(path))
if (Utils.PathIsUnc(path, networkOnly : true))
{
return true;
}
@@ -228,6 +228,18 @@ Describe "Get-ChildItem" -Tags "CI" {
$barFiles = Get-ChildItem -Path testdrive:/foo/bar -Recurse
$barFiles.Count | Should -Be 2
}
It 'Works with Windows volume paths' -Skip:(!$IsWindows) {
$volume = (Get-Volume -DriveLetter $env:SystemDrive[0]).Path
$items = Get-ChildItem -LiteralPath "${volume}Windows"
$items[0].Parent | Should -BeExactly "${volume}Windows"
$items | Should -HaveCount (Get-ChildItem $env:SystemRoot).Count
}
It 'Works with Windows pipes' -Skip:(!$IsWindows) {
$out = pwsh -noprofile -custompipename myTestPipe { Get-ChildItem \\.\pipe\myTestPipe }
$out.Name | Should -BeExactly 'myTestPipe'
}
}
Context 'Env: Provider' {