From 154a1ee913770328e720c394eff5b09c1f5c3602 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Mon, 14 Aug 2017 02:00:53 -0700 Subject: [PATCH 1/5] AlternateStreams support relies on pinvoke to win32 apis which don't work on non-Windows and produces errors about not loading a dll in the case of copy-item --- .../commands/utility/UnblockFile.cs | 4 ++- .../engine/Modules/ImportModuleCommand.cs | 2 ++ .../namespaces/FileSystemContentStream.cs | 4 +++ .../namespaces/FileSystemProvider.cs | 32 ++++++++++++++++--- .../utils/ClrFacade.cs | 11 +++---- .../Get-Content.Tests.ps1 | 13 ++++++++ 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs index 0f3a4cdc09e..6d17bef192b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs @@ -14,6 +14,7 @@ #endregion +#if !UNIX namespace Microsoft.PowerShell.Commands { /// Removes the Zone.Identifier stream from a file. @@ -161,4 +162,5 @@ private bool IsValidFileForUnblocking(string resolvedpath) return isValidUnblockableFile; } } -} \ No newline at end of file +} +#endif diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index 780cc60deef..dbd058cab1b 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -1304,7 +1304,9 @@ private IEnumerable CreateCimModuleFiles( fullPath, file.RawFileData); +#if !UNIX AlternateDataStreamUtilities.SetZoneOfOrigin(fullPath, SecurityZone.Intranet); +#endif } return relativePathsToCreatedFiles; diff --git a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs index 999eca632bb..4c7ce07b69b 100644 --- a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs +++ b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs @@ -843,7 +843,9 @@ private void CreateStreams(string filePath, string streamName, FileMode fileMode { if (!String.IsNullOrEmpty(streamName)) { +#if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, fileAccess, fileShare); +#endif } else { @@ -854,7 +856,9 @@ private void CreateStreams(string filePath, string streamName, FileMode fileMode { if (!String.IsNullOrEmpty(streamName)) { +#if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, requestedAccess, fileShare); +#endif } else { diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 25467fc2aed..3d7886ddf76 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -1117,6 +1117,7 @@ protected override void GetItem(string path) try { +#if !UNIX bool retrieveStreams = false; FileSystemProviderGetItemDynamicParameters dynamicParameters = null; @@ -1146,10 +1147,12 @@ protected override void GetItem(string path) } } } +#endif FileSystemInfo result = GetFileSystemItem(path, ref isContainer, false); if (result != null) { +#if !UNIX // If we want to retrieve the file streams, retrieve them. if (retrieveStreams) { @@ -1186,6 +1189,7 @@ protected override void GetItem(string path) } } else +#endif { // Otherwise, return the item itself. WriteItemObject(result, result.FullName, isContainer); @@ -2758,6 +2762,7 @@ protected override void RemoveItem(string path, bool recurse) { path = NormalizePath(path); +#if !UNIX bool removeStreams = false; FileSystemProviderRemoveItemDynamicParameters dynamicParameters = null; @@ -2787,6 +2792,7 @@ protected override void RemoveItem(string path, bool recurse) } } } +#endif bool iscontainer = false; FileSystemInfo fsinfo = GetFileSystemInfo(path, ref iscontainer); @@ -2798,12 +2804,17 @@ protected override void RemoveItem(string path, bool recurse) return; } +#if !UNIX if ((!removeStreams) && iscontainer) +#else + if (iscontainer) +#endif { RemoveDirectoryInfoItem((DirectoryInfo)fsinfo, recurse, Force, true); } else { +#if !UNIX // If we want to remove the file streams, retrieve them and remove them. if (removeStreams) { @@ -2843,6 +2854,7 @@ protected override void RemoveItem(string path, bool recurse) } } else +#endif { RemoveFileInfoItem((FileInfo)fsinfo, Force); } @@ -4233,12 +4245,13 @@ private bool PerformCopyFileFromRemoteSession(string sourceFileFullName, FileInf wStream = new FileStream(destinationFile.FullName, FileMode.Create); } +#if !UNIX // an alternate stream else { wStream = AlternateDataStreamUtilities.CreateFileStream(destinationFile.FullName, streamName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); } - +#endif long fragmentSize = FILETRANSFERSIZE; long copiedSoFar = 0; long currentIndex = 0; @@ -4498,11 +4511,12 @@ private bool CopyFileStreamToRemoteSession(FileInfo file, string destinationPath { fStream = File.OpenRead(file.FullName); } +#if !UNIX else { fStream = AlternateDataStreamUtilities.CreateFileStream(file.FullName, streamName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } - +#endif long remainingFileSize = fStream.Length; do { @@ -4667,6 +4681,7 @@ private bool PerformCopyFileToRemoteSession(FileInfo file, string destinationPat bool targetSupportsAlternateStreams = RemoteTargetSupportsAlternateStreams(ps, remoteFilePath); +#if !UNIX // Once the file is copied successfully, check if the file has any alternate data streams if (result && targetSupportsAlternateStreams) { @@ -4682,7 +4697,7 @@ private bool PerformCopyFileToRemoteSession(FileInfo file, string destinationPat } } } - +#endif if (result) { SetRemoteFileMetadata(file, Path.Combine(destinationPath, file.Name), ps); @@ -6828,10 +6843,11 @@ public void ClearContent(string path) try { +#if !UNIX bool clearStream = false; + string streamName = null; FileSystemClearContentDynamicParameters dynamicParameters = null; FileSystemContentWriterDynamicParameters writerDynamicParameters = null; - string streamName = null; // We get called during: // - Clear-Content @@ -6900,6 +6916,7 @@ public void ClearContent(string path) } } else +#endif { string action = FileSystemProviderStrings.ClearContentActionFile; string resource = StringUtil.Format(FileSystemProviderStrings.ClearContentesourceTemplate, path); @@ -8260,6 +8277,7 @@ internal static bool IsSameFileSystemItem(string pathOne, string pathTwo) #endif } +#if !UNIX internal static bool WinIsSameFileSystemItem(string pathOne, string pathTwo) { var access = FileAccess.Read; @@ -8286,6 +8304,7 @@ internal static bool WinIsSameFileSystemItem(string pathOne, string pathTwo) return false; } +#endif internal static bool GetInodeData(string path, out System.ValueTuple inodeData) { @@ -8297,6 +8316,7 @@ internal static bool GetInodeData(string path, out System.ValueTuple inodeData) { var access = FileAccess.Read; @@ -8325,7 +8345,7 @@ internal static bool WinGetInodeData(string path, out System.ValueTuple @@ -8847,6 +8868,7 @@ internal class AlternateStreamNativeData } #endregion +#endif #region CopyFileFromRemoteUtils diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index 7044465b05b..b360170fa0a 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -147,7 +147,6 @@ internal static SecurityZone GetFileSecurityZone(string filePath) { Diagnostics.Assert(Path.IsPathRooted(filePath), "Caller makes sure the path is rooted."); Diagnostics.Assert(Utils.NativeFileExists(filePath), "Caller makes sure the file exists."); -#if CORECLR string sysRoot = System.Environment.GetEnvironmentVariable("SystemRoot"); string urlmonPath = Path.Combine(sysRoot, @"System32\urlmon.dll"); if (Utils.NativeFileExists(urlmonPath)) @@ -155,12 +154,8 @@ internal static SecurityZone GetFileSecurityZone(string filePath) return MapSecurityZoneWithUrlmon(filePath); } return MapSecurityZoneWithoutUrlmon(filePath); -#else - return MapSecurityZoneWithUrlmon(filePath); -#endif } -#if CORECLR #region WithoutUrlmon /// @@ -202,9 +197,10 @@ internal static SecurityZone GetFileSecurityZone(string filePath) /// private static SecurityZone MapSecurityZoneWithoutUrlmon(string filePath) { +#if !UNIX SecurityZone reval = ReadFromZoneIdentifierDataStream(filePath); if (reval != SecurityZone.NoZone) { return reval; } - +#endif // If it reaches here, then we either couldn't get the ZoneId information, or the ZoneId is invalid. // In this case, we try to determine the SecurityZone by analyzing the file path. Uri uri = new Uri(filePath); @@ -243,6 +239,7 @@ private static SecurityZone MapSecurityZoneWithoutUrlmon(string filePath) } } +#if !UNIX /// /// Read the 'Zone.Identifier' alternate data stream to determin SecurityZone of the file. /// @@ -302,8 +299,8 @@ private static SecurityZone ReadFromZoneIdentifierDataStream(string filePath) return SecurityZone.NoZone; } - #endregion WithoutUrlmon #endif + #endregion WithoutUrlmon /// /// Map the file to SecurityZone using urlmon.dll, depending on 'IInternetSecurityManager::MapUrlToZone'. diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 index 0b3215f4e6b..90fc04a403b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 @@ -126,4 +126,17 @@ Describe "Get-Content" -Tags "CI" { } else {$expected = "Hell","o,ll","ll","Worll","d`nHell","o2,ll","ll","Worll","d2`n"} for ($i = 0; $i -lt $result.Length ; $i++) { $result[$i] | Should BeExactly $expected[$i]} } + + It "Should support NTFS streams using colon syntax" -Skip:(!$IsWindows) { + Set-Content "${testPath}:Stream" -Value "Foo" + { Test_path "${testPath}:Stream" | ShouldBeErrorId "ItemExistsNotSupportedError,Microsoft.PowerShell.Commands,TestPathCommand" } + Get-Content "${testPath}:Stream" | Should BeExactly "Foo" + Get-Content $testPath | Should BeExactly $testString + } + + It "Should support colons in filename on Linux/Mac" -Skip:($IsWindows) { + Set-Content "${testPath}:Stream" -Value "Hello" + Get-Content "${testPath}:Stream" | Should BeExactly "Hello" + } + } From 77cc9d96457c41e25a1444d2af582fe052fc99ac Mon Sep 17 00:00:00 2001 From: "Steve Lee [MSFT]" Date: Mon, 14 Aug 2017 15:24:37 -0700 Subject: [PATCH 2/5] address PR feedback --- .../commands/utility/UnblockFile.cs | 2 +- src/System.Management.Automation/utils/ClrFacade.cs | 2 ++ .../Microsoft.PowerShell.Management/Get-Content.Tests.ps1 | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs index 6d17bef192b..95d91473183 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UnblockFile.cs @@ -1,3 +1,4 @@ +#if !UNIX /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -14,7 +15,6 @@ #endregion -#if !UNIX namespace Microsoft.PowerShell.Commands { /// Removes the Zone.Identifier stream from a file. diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index b360170fa0a..03465eeb13c 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -147,12 +147,14 @@ internal static SecurityZone GetFileSecurityZone(string filePath) { Diagnostics.Assert(Path.IsPathRooted(filePath), "Caller makes sure the path is rooted."); Diagnostics.Assert(Utils.NativeFileExists(filePath), "Caller makes sure the file exists."); +#if !UNIX string sysRoot = System.Environment.GetEnvironmentVariable("SystemRoot"); string urlmonPath = Path.Combine(sysRoot, @"System32\urlmon.dll"); if (Utils.NativeFileExists(urlmonPath)) { return MapSecurityZoneWithUrlmon(filePath); } +#endif return MapSecurityZoneWithoutUrlmon(filePath); } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 index 90fc04a403b..730e46ac398 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 @@ -129,13 +129,14 @@ Describe "Get-Content" -Tags "CI" { It "Should support NTFS streams using colon syntax" -Skip:(!$IsWindows) { Set-Content "${testPath}:Stream" -Value "Foo" - { Test_path "${testPath}:Stream" | ShouldBeErrorId "ItemExistsNotSupportedError,Microsoft.PowerShell.Commands,TestPathCommand" } + { Test-Path "${testPath}:Stream" | ShouldBeErrorId "ItemExistsNotSupportedError,Microsoft.PowerShell.Commands,TestPathCommand" } Get-Content "${testPath}:Stream" | Should BeExactly "Foo" Get-Content $testPath | Should BeExactly $testString } It "Should support colons in filename on Linux/Mac" -Skip:($IsWindows) { Set-Content "${testPath}:Stream" -Value "Hello" + "${testPath}:Stream" | Should Exist Get-Content "${testPath}:Stream" | Should BeExactly "Hello" } From 6ae0bf9c7f075cb22358f5b3ac6d3493662ce187 Mon Sep 17 00:00:00 2001 From: "Steve Lee [MSFT]" Date: Wed, 16 Aug 2017 02:45:05 -0700 Subject: [PATCH 3/5] address PR feedback --- .../namespaces/FileSystemContentStream.cs | 4 ++++ .../namespaces/FileSystemProvider.cs | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs index 4c7ce07b69b..5bf6a2de9c5 100644 --- a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs +++ b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs @@ -845,6 +845,8 @@ private void CreateStreams(string filePath, string streamName, FileMode fileMode { #if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, fileAccess, fileShare); +#else + throw new PlatformNotSupportedException(); #endif } else @@ -858,6 +860,8 @@ private void CreateStreams(string filePath, string streamName, FileMode fileMode { #if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, requestedAccess, fileShare); +#else + throw new PlatformNotSupportedException(); #endif } else diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 3d7886ddf76..b61c9a0405f 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -2804,17 +2804,22 @@ protected override void RemoveItem(string path, bool recurse) return; } -#if !UNIX - if ((!removeStreams) && iscontainer) -#else +#if UNIX if (iscontainer) -#endif { RemoveDirectoryInfoItem((DirectoryInfo)fsinfo, recurse, Force, true); } else { -#if !UNIX + RemoveFileInfoItem((FileInfo)fsinfo, Force); + } +#else + if ((!removeStreams) && iscontainer) + { + RemoveDirectoryInfoItem((DirectoryInfo)fsinfo, recurse, Force, true); + } + else + { // If we want to remove the file streams, retrieve them and remove them. if (removeStreams) { @@ -2854,11 +2859,11 @@ protected override void RemoveItem(string path, bool recurse) } } else -#endif { RemoveFileInfoItem((FileInfo)fsinfo, Force); } } +#endif } catch (IOException exception) { @@ -4267,11 +4272,13 @@ private bool PerformCopyFileFromRemoteSession(string sourceFileFullName, FileInf ps.AddParameter("force", true); } +#if !UNIX if (isAlternateDataStream) { ps.AddParameter("isAlternateStream", true); ps.AddParameter("streamName", streamName); } +#endif Hashtable op = SafeInvokeCommand.Invoke(ps, this, null); From aed2f247e4a3de24e38940075041af1f9f71d4e4 Mon Sep 17 00:00:00 2001 From: "Steve Lee [MSFT]" Date: Wed, 16 Aug 2017 16:23:41 -0700 Subject: [PATCH 4/5] address PR feedback, remove -Stream parameter for Unix added new -stream tests --- .../namespaces/FileSystemContentStream.cs | 12 ++++------ .../namespaces/FileSystemProvider.cs | 17 ++++++++++--- .../security/SecurityManager.cs | 4 ++++ .../utils/ClrFacade.cs | 8 ++----- .../Clear-Content.Tests.ps1 | 2 +- .../Get-Content.Tests.ps1 | 24 +++++++++++++++++++ 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs index 5bf6a2de9c5..6648c9de52c 100644 --- a/src/System.Management.Automation/namespaces/FileSystemContentStream.cs +++ b/src/System.Management.Automation/namespaces/FileSystemContentStream.cs @@ -841,30 +841,26 @@ private void CreateStreams(string filePath, string streamName, FileMode fileMode try { +#if !UNIX if (!String.IsNullOrEmpty(streamName)) { -#if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, fileAccess, fileShare); -#else - throw new PlatformNotSupportedException(); -#endif } else +#endif { _stream = new FileStream(filePath, fileMode, fileAccess, fileShare); } } catch (IOException) { +#if !UNIX if (!String.IsNullOrEmpty(streamName)) { -#if !UNIX _stream = AlternateDataStreamUtilities.CreateFileStream(filePath, streamName, fileMode, requestedAccess, fileShare); -#else - throw new PlatformNotSupportedException(); -#endif } else +#endif { _stream = new FileStream(filePath, fileMode, requestedAccess, fileShare); } diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index b61c9a0405f..0c017b24381 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -6612,8 +6612,10 @@ public IContentReader GetContentReader(string path) // Get the wait value waitForChanges = dynParams.Wait; +#if !UNIX // Get the stream name streamName = dynParams.Stream; +#endif } // dynParams != null } // DynamicParameters != null @@ -6756,7 +6758,9 @@ public IContentWriter GetContentWriter(string path) encoding = dynParams.EncodingType; } +#if !UNIX streamName = dynParams.Stream; +#endif suppressNewline = dynParams.NoNewline.IsPresent; } // dynParams != null } @@ -7628,12 +7632,13 @@ public class FileSystemContentDynamicParametersBase [Parameter] public FileSystemCmdletProviderEncoding Encoding { get; set; } = FileSystemCmdletProviderEncoding.String; +#if !UNIX /// /// A parameter to return a stream of an item. /// [Parameter] public String Stream { get; set; } - +#endif /// /// Gets the encoding from the specified StreamType parameter. @@ -7677,11 +7682,13 @@ public bool WasStreamTypeSpecified /// public class FileSystemClearContentDynamicParameters { +#if !UNIX /// /// A parameter to return a stream of an item. /// [Parameter] public String Stream { get; set; } +#endif } //FileSystemContentWriterDynamicParameters /// @@ -7805,6 +7812,7 @@ public class FileSystemItemProviderDynamicParameters /// public class FileSystemProviderGetItemDynamicParameters { +#if !UNIX /// /// A parameter to return the streams of an item. /// @@ -7812,6 +7820,7 @@ public class FileSystemProviderGetItemDynamicParameters [ValidateNotNullOrEmpty()] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] Stream { get; set; } +#endif } // class FileSystemItemProviderDynamicParameters /// @@ -7819,6 +7828,7 @@ public class FileSystemProviderGetItemDynamicParameters /// public class FileSystemProviderRemoveItemDynamicParameters { +#if !UNIX /// /// A parameter to return the streams of an item. /// @@ -7826,6 +7836,7 @@ public class FileSystemProviderRemoveItemDynamicParameters [ValidateNotNullOrEmpty()] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] Stream { get; set; } +#endif } // class FileSystemItemProviderDynamicParameters #endregion @@ -8285,7 +8296,7 @@ internal static bool IsSameFileSystemItem(string pathOne, string pathTwo) } #if !UNIX - internal static bool WinIsSameFileSystemItem(string pathOne, string pathTwo) + private static bool WinIsSameFileSystemItem(string pathOne, string pathTwo) { var access = FileAccess.Read; var share = FileShare.Read; @@ -8324,7 +8335,7 @@ internal static bool GetInodeData(string path, out System.ValueTuple inodeData) + private static bool WinGetInodeData(string path, out System.ValueTuple inodeData) { var access = FileAccess.Read; var share = FileShare.Read; diff --git a/src/System.Management.Automation/security/SecurityManager.cs b/src/System.Management.Automation/security/SecurityManager.cs index 59bb13d78a4..fabde5335f8 100644 --- a/src/System.Management.Automation/security/SecurityManager.cs +++ b/src/System.Management.Automation/security/SecurityManager.cs @@ -402,6 +402,9 @@ private bool SetPolicyFromAuthenticodePrompt(string path, PSHost host, ref Excep private bool IsLocalFile(string filename) { +#if UNIX + return true; +#else SecurityZone zone = ClrFacade.GetFileSecurityZone(filename); if (zone == SecurityZone.MyComputer || @@ -412,6 +415,7 @@ private bool IsLocalFile(string filename) } return false; +#endif } // Checks that a publisher is trusted by the system or is one of diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index 03465eeb13c..03c4b252c88 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -138,6 +138,7 @@ private static void EncodingRegisterProvider() #endregion Encoding +#if !UNIX #region Security /// @@ -147,14 +148,12 @@ internal static SecurityZone GetFileSecurityZone(string filePath) { Diagnostics.Assert(Path.IsPathRooted(filePath), "Caller makes sure the path is rooted."); Diagnostics.Assert(Utils.NativeFileExists(filePath), "Caller makes sure the file exists."); -#if !UNIX string sysRoot = System.Environment.GetEnvironmentVariable("SystemRoot"); string urlmonPath = Path.Combine(sysRoot, @"System32\urlmon.dll"); if (Utils.NativeFileExists(urlmonPath)) { return MapSecurityZoneWithUrlmon(filePath); } -#endif return MapSecurityZoneWithoutUrlmon(filePath); } @@ -199,10 +198,8 @@ internal static SecurityZone GetFileSecurityZone(string filePath) /// private static SecurityZone MapSecurityZoneWithoutUrlmon(string filePath) { -#if !UNIX SecurityZone reval = ReadFromZoneIdentifierDataStream(filePath); if (reval != SecurityZone.NoZone) { return reval; } -#endif // If it reaches here, then we either couldn't get the ZoneId information, or the ZoneId is invalid. // In this case, we try to determine the SecurityZone by analyzing the file path. Uri uri = new Uri(filePath); @@ -241,7 +238,6 @@ private static SecurityZone MapSecurityZoneWithoutUrlmon(string filePath) } } -#if !UNIX /// /// Read the 'Zone.Identifier' alternate data stream to determin SecurityZone of the file. /// @@ -301,7 +297,6 @@ private static SecurityZone ReadFromZoneIdentifierDataStream(string filePath) return SecurityZone.NoZone; } -#endif #endregion WithoutUrlmon /// @@ -341,6 +336,7 @@ private static SecurityZone MapSecurityZoneWithUrlmon(string filePath) } #endregion Security +#endif #region Misc diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Clear-Content.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Clear-Content.Tests.ps1 index 7eecdbfa17e..8c9c1c1aea9 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Clear-Content.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Clear-Content.Tests.ps1 @@ -83,7 +83,7 @@ Describe "Clear-Content cmdlet tests" -Tags "CI" { get-content -Path "TESTDRIVE:/$file3" -stream $streamName | should BeNullOrEmpty } - It "the '-Stream' dynamic parameter is visible to get-command in the filesystem" { + It "the '-Stream' dynamic parameter is visible to get-command in the filesystem" -Skip:(!$IsWindows) { try { push-location TESTDRIVE: (get-command clear-content -stream foo).parameters.keys -eq "stream" | should be "stream" diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 index 730e46ac398..c35e5a19cce 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Content.Tests.ps1 @@ -134,10 +134,34 @@ Describe "Get-Content" -Tags "CI" { Get-Content $testPath | Should BeExactly $testString } + It "Should support NTFS streams using -stream" -Skip:(!$IsWindows) { + Set-Content -Path $testPath -Stream hello -Value World + Get-Content -Path $testPath | Should Be $testString + Get-Content -Path $testPath -Stream hello | Should Be "World" + $item = Get-Item -Path $testPath -Stream hello + $item | Should BeOfType System.Management.Automation.Internal.AlternateStreamData + $item.Stream | Should Be "hello" + Clear-Content -Path $testPath -Stream hello + Get-Content -Path $testPath -Stream hello | Should BeNullOrEmpty + Remove-Item -Path $testPath -Stream hello + { Get-Content -Path $testPath -Stream hello | ShouldBeErrorId "GetContentReaderFileNotFoundError,Microsoft.PowerShell.Commands.GetContentCommand" } + } + It "Should support colons in filename on Linux/Mac" -Skip:($IsWindows) { Set-Content "${testPath}:Stream" -Value "Hello" "${testPath}:Stream" | Should Exist Get-Content "${testPath}:Stream" | Should BeExactly "Hello" } + It "-Stream is not a valid parameter for on Linux/Mac" -Skip:($IsWindows) -TestCases @( + @{cmdlet="get-content"}, + @{cmdlet="set-content"}, + @{cmdlet="clear-content"}, + @{cmdlet="add-content"}, + @{cmdlet="get-item"}, + @{cmdlet="remove-item"} + ) { + param($cmdlet) + (Get-Command $cmdlet).Parameters["stream"] | Should BeNullOrEmpty + } } From 7701b7a807d0e425364c73bf5f530a40163e2c84 Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL)" Date: Mon, 21 Aug 2017 13:17:00 -0700 Subject: [PATCH 5/5] ifdef out alternate stream syntax checks not applicable to unix --- .../namespaces/FileSystemProvider.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 0c017b24381..384674430dc 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -1046,6 +1046,7 @@ protected override bool IsValidPath(string path) path = NormalizePath(path); path = EnsureDriveIsRooted(path); +#if !UNIX // Remove alternate data stream references // See if they've used the inline stream syntax. They have more than one colon. int firstColon = path.IndexOf(':'); @@ -1054,6 +1055,7 @@ protected override bool IsValidPath(string path) { path = path.Substring(0, secondColon); } +#endif //Make sure the path is either drive rooted or UNC Path if (!IsAbsolutePath(path) && !IsUNCPath(path)) @@ -4686,9 +4688,9 @@ private bool PerformCopyFileToRemoteSession(FileInfo file, string destinationPat bool result = CopyFileStreamToRemoteSession(file, remoteFilePath, ps, false, null); +#if !UNIX bool targetSupportsAlternateStreams = RemoteTargetSupportsAlternateStreams(ps, remoteFilePath); -#if !UNIX // Once the file is copied successfully, check if the file has any alternate data streams if (result && targetSupportsAlternateStreams) { @@ -5165,6 +5167,7 @@ private string NormalizeRelativePathHelper(string path, string basePath) s_tracer.WriteLine("basePath = {0}", basePath); +#if !UNIX // Remove alternate data stream references // See if they've used the inline stream syntax. They have more than one colon. string alternateDataStream = String.Empty; @@ -5176,6 +5179,7 @@ private string NormalizeRelativePathHelper(string path, string basePath) alternateDataStream = path.Replace(newPath, ""); path = newPath; } +#endif string result = path; @@ -5299,10 +5303,12 @@ private string NormalizeRelativePathHelper(string path, string basePath) } } while (false); +#if !UNIX if (!String.IsNullOrEmpty(alternateDataStream)) { result = result + alternateDataStream; } +#endif return result; } // NormalizeRelativePathHelper @@ -6619,6 +6625,7 @@ public IContentReader GetContentReader(string path) } // dynParams != null } // DynamicParameters != null +#if !UNIX // See if they've used the inline stream syntax. They have more than one colon. int firstColon = path.IndexOf(':'); int secondColon = path.IndexOf(':', firstColon + 1); @@ -6627,6 +6634,7 @@ public IContentReader GetContentReader(string path) streamName = path.Substring(secondColon + 1); path = path.Remove(secondColon); } +#endif FileSystemContentReaderWriter stream = null; @@ -6765,6 +6773,7 @@ public IContentWriter GetContentWriter(string path) } // dynParams != null } +#if !UNIX // See if they've used the inline stream syntax. They have more than one colon. int firstColon = path.IndexOf(':'); int secondColon = path.IndexOf(':', firstColon + 1); @@ -6773,6 +6782,7 @@ public IContentWriter GetContentWriter(string path) streamName = path.Substring(secondColon + 1); path = path.Remove(secondColon); } +#endif FileSystemContentReaderWriter stream = null;