diff --git a/src/System.Management.Automation/engine/Interop/Windows/WNetGetConnection.cs b/src/System.Management.Automation/engine/Interop/Windows/WNetGetConnection.cs index bf7742526f1..fcdaeb65d3c 100644 --- a/src/System.Management.Automation/engine/Interop/Windows/WNetGetConnection.cs +++ b/src/System.Management.Automation/engine/Interop/Windows/WNetGetConnection.cs @@ -13,8 +13,8 @@ internal static unsafe partial class Windows { private static bool s_WNetApiNotAvailable; - [LibraryImport("mpr.dll", EntryPoint = "WNetGetConnectionW")] - internal static partial int WNetGetConnection(ReadOnlySpan localName, Span remoteName, ref uint remoteNameLength); + [LibraryImport("mpr.dll", EntryPoint = "WNetGetConnectionW", StringMarshalling = StringMarshalling.Utf16)] + internal static partial int WNetGetConnection(ReadOnlySpan localName, Span remoteName, ref uint remoteNameLength); internal static int GetUNCForNetworkDrive(char drive, out string? uncPath) { @@ -33,11 +33,8 @@ internal static int GetUNCForNetworkDrive(char drive, out string? uncPath) bufferSize = 3; #endif - // TODO: change ushort with char after LibraryImport will support 'ref char' - // without applying the 'System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute' - // to the assembly. - ReadOnlySpan driveName = stackalloc ushort[] { drive, ':', '\0' }; - Span uncBuffer = stackalloc ushort[(int)bufferSize]; + ReadOnlySpan driveName = stackalloc char[] { drive, ':', '\0' }; + Span uncBuffer = stackalloc char[(int)bufferSize]; int errorCode = ERROR_NO_NETWORK; try @@ -52,26 +49,28 @@ internal static int GetUNCForNetworkDrive(char drive, out string? uncPath) if (errorCode == ERROR_SUCCESS) { - uncPath = uncBuffer.Slice((int)bufferSize).ToString(); + // exclude null terminator + uncPath = uncBuffer.Slice(0, (int)bufferSize - 1).ToString(); } else if (errorCode == ERROR_MORE_DATA) { - ushort[]? rentedArray = null; + char[]? rentedArray = null; try { - uncBuffer = rentedArray = ArrayPool.Shared.Rent((int)bufferSize); + uncBuffer = rentedArray = ArrayPool.Shared.Rent((int)bufferSize); errorCode = WNetGetConnection(driveName, uncBuffer, ref bufferSize); if (errorCode == ERROR_SUCCESS) { - uncPath = uncBuffer.Slice((int)bufferSize).ToString(); + // exclude null terminator + uncPath = uncBuffer.Slice(0, (int)bufferSize - 1).ToString(); } } finally { if (rentedArray is not null) { - ArrayPool.Shared.Return(rentedArray); + ArrayPool.Shared.Return(rentedArray); } } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/New-PSDrive.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/New-PSDrive.Tests.ps1 index 77d76b6ec6a..3894b5a0257 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/New-PSDrive.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/New-PSDrive.Tests.ps1 @@ -17,6 +17,12 @@ Describe "Tests for New-PSDrive cmdlet." -Tag "CI","RequireAdminOnWindows" { { New-PSDrive -Name $PSDriveName -PSProvider FileSystem -Root $RemoteShare -Persist -ErrorAction Stop } | Should -Not -Throw } + It "Network drive initialization on pwsh startup DisplayRoot should have value of share" -Skip:(-not $IsWindows) { + $null = New-PSDrive -Name $PSDriveName -PSProvider FileSystem -Root $RemoteShare -Persist -ErrorAction Stop + $drive = pwsh -noprofile -outputformat XML -command "Get-PSDrive -Name $PSDriveName" + $drive.DisplayRoot | Should -Be $RemoteShare.TrimEnd('\') + } + It "Should throw exception if root is not a remote share." -Skip:(-not $IsWindows) { { New-PSDrive -Name $PSDriveName -PSProvider FileSystem -Root "TestDrive:\" -Persist -ErrorAction Stop } | Should -Throw -ErrorId 'DriveRootNotNetworkPath' }