From 91bf34679c85e4417318573440bf5450ce193fa9 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 3 Oct 2019 19:41:18 +0500 Subject: [PATCH] Read special reparse points without accessing it (#10662) * Enhance enum FileDesiredAccess with zero value GenericZero * Use the GenericZero as desired access mode to read reparse point without access it From docs: If desired access is zero, the application can query certain metadata such as file, directory, or device attributes without accessing that file or device, even if GENERIC_READ access would have been denied --- .../namespaces/FileSystemProvider.cs | 13 +++++++++++-- .../Get-Item.Tests.ps1 | 9 +++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index f731a32273..88f2eb51ec 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -7712,6 +7712,7 @@ namespace Microsoft.PowerShell.Commands // dwDesiredAccess of CreateFile internal enum FileDesiredAccess : uint { + GenericZero = 0, GenericRead = 0x80000000, GenericWrite = 0x40000000, GenericExecute = 0x20000000, @@ -7917,7 +7918,11 @@ namespace Microsoft.PowerShell.Commands if (instance.BaseObject is FileSystemInfo fileSysInfo) { #if !UNIX - using (SafeFileHandle handle = OpenReparsePoint(fileSysInfo.FullName, FileDesiredAccess.GenericRead)) + // We set accessMode parameter to zero because documentation says: + // If this parameter is zero, the application can query certain metadata + // such as file, directory, or device attributes without accessing + // that file or device, even if GENERIC_READ access would have been denied. + using (SafeFileHandle handle = OpenReparsePoint(fileSysInfo.FullName, FileDesiredAccess.GenericZero)) { string linkTarget = WinInternalGetTarget(handle); @@ -7982,7 +7987,11 @@ namespace Microsoft.PowerShell.Commands throw new PlatformNotSupportedException(); } - using (SafeFileHandle handle = OpenReparsePoint(filePath, FileDesiredAccess.GenericRead)) + // We set accessMode parameter to zero because documentation says: + // If this parameter is zero, the application can query certain metadata + // such as file, directory, or device attributes without accessing + // that file or device, even if GENERIC_READ access would have been denied. + using (SafeFileHandle handle = OpenReparsePoint(filePath, FileDesiredAccess.GenericZero)) { int outBufferSize = Marshal.SizeOf(); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Item.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Item.Tests.ps1 index d1e37919d8..c9be5e10f8 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Item.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Item.Tests.ps1 @@ -52,6 +52,15 @@ Describe "Get-Item" -Tags "CI" { ${result}.FullName | Should -BeExactly ${item}.FullName } + It "Should get properties for special reparse points" -skip:$skipNotWindows { + $result = Get-Item -Path $HOME/Cookies -Force + $result.LinkType | Should -BeExactly "Junction" + $result.Target | Should -Not -BeNullOrEmpty + $result.Name | Should -BeExactly "Cookies" + $result.Mode | Should -BeExactly "l--hs" + $result.Exists | Should -BeTrue + } + Context "Test for Include, Exclude, and Filter" { BeforeAll { ${testBaseDir} = "${TESTDRIVE}/IncludeExclude"