Skip to content

Commit d72cedd

Browse files
authored
Fix FileSystemProvider to work with volume and pipe paths (PowerShell#15873)
1 parent 1a8d23f commit d72cedd

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

src/System.Management.Automation/engine/Utils.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ internal static bool IsReservedDeviceName(string destinationPath)
12811281
return false;
12821282
}
12831283

1284-
internal static bool PathIsUnc(string path)
1284+
internal static bool PathIsUnc(string path, bool networkOnly = false)
12851285
{
12861286
#if UNIX
12871287
return false;
@@ -1291,8 +1291,8 @@ internal static bool PathIsUnc(string path)
12911291
return false;
12921292
}
12931293

1294-
// handle special cases like \\wsl$\ubuntu which isn't a UNC path, but we can say it is so the filesystemprovider can use it
1295-
if (path.StartsWith(WslRootPath, StringComparison.OrdinalIgnoreCase))
1294+
// 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
1295+
if (!networkOnly && (path.StartsWith(WslRootPath, StringComparison.OrdinalIgnoreCase) || path.StartsWith("\\\\?\\") || path.StartsWith("\\\\.\\")))
12961296
{
12971297
return true;
12981298
}

src/System.Management.Automation/namespaces/FileSystemProvider.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,21 @@ private static string GetCorrectCasedPath(string path)
132132
itemsToSkip = 4;
133133
}
134134

135-
foreach (string item in path.Split(StringLiterals.DefaultPathSeparator))
135+
var items = path.Split(StringLiterals.DefaultPathSeparator);
136+
for (int i = 0; i < items.Length; i++)
136137
{
137138
if (itemsToSkip-- > 0)
138139
{
139140
// This handles the UNC server and share and 8.3 short path syntax
140-
exactPath += item + StringLiterals.DefaultPathSeparator;
141+
exactPath += items[i] + StringLiterals.DefaultPathSeparator;
141142
continue;
142143
}
143144
else if (string.IsNullOrEmpty(exactPath))
144145
{
145146
// This handles the drive letter or / root path start
146-
exactPath = item + StringLiterals.DefaultPathSeparator;
147+
exactPath = items[i] + StringLiterals.DefaultPathSeparator;
147148
}
148-
else if (string.IsNullOrEmpty(item))
149+
else if (string.IsNullOrEmpty(items[i]) && i == items.Length - 1)
149150
{
150151
// This handles the trailing slash case
151152
if (!exactPath.EndsWith(StringLiterals.DefaultPathSeparator))
@@ -155,17 +156,17 @@ private static string GetCorrectCasedPath(string path)
155156

156157
break;
157158
}
158-
else if (item.Contains('~'))
159+
else if (items[i].Contains('~'))
159160
{
160161
// This handles short path names
161-
exactPath += StringLiterals.DefaultPathSeparator + item;
162+
exactPath += StringLiterals.DefaultPathSeparator + items[i];
162163
}
163164
else
164165
{
165166
// Use GetFileSystemEntries to get the correct casing of this element
166167
try
167168
{
168-
var entries = Directory.GetFileSystemEntries(exactPath, item);
169+
var entries = Directory.GetFileSystemEntries(exactPath, items[i]);
169170
if (entries.Length > 0)
170171
{
171172
exactPath = entries[0];
@@ -7257,7 +7258,7 @@ internal static bool PathIsNetworkPath(string path)
72577258
return false;
72587259
}
72597260

7260-
if (Utils.PathIsUnc(path))
7261+
if (Utils.PathIsUnc(path, networkOnly : true))
72617262
{
72627263
return true;
72637264
}

test/powershell/Modules/Microsoft.PowerShell.Management/Get-ChildItem.Tests.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,18 @@ Describe "Get-ChildItem" -Tags "CI" {
228228
$barFiles = Get-ChildItem -Path testdrive:/foo/bar -Recurse
229229
$barFiles.Count | Should -Be 2
230230
}
231+
232+
It 'Works with Windows volume paths' -Skip:(!$IsWindows) {
233+
$volume = (Get-Volume -DriveLetter $env:SystemDrive[0]).Path
234+
$items = Get-ChildItem -LiteralPath "${volume}Windows"
235+
$items[0].Parent | Should -BeExactly "${volume}Windows"
236+
$items | Should -HaveCount (Get-ChildItem $env:SystemRoot).Count
237+
}
238+
239+
It 'Works with Windows pipes' -Skip:(!$IsWindows) {
240+
$out = pwsh -noprofile -custompipename myTestPipe { Get-ChildItem \\.\pipe\myTestPipe }
241+
$out.Name | Should -BeExactly 'myTestPipe'
242+
}
231243
}
232244

233245
Context 'Env: Provider' {

0 commit comments

Comments
 (0)