Fix 'Get-ChildItem -Hidden' to work on system hidden files like c:\hiberfil.sys c:\pagefile.sys and c:\swapfile.sys

This commit is contained in:
Charu Bassi
2016-09-27 16:13:03 -07:00
committed by Dongbo Wang
parent 379cc52b95
commit 5cbf1b43de
3 changed files with 71 additions and 7 deletions
@@ -996,7 +996,27 @@ namespace System.Management.Automation
Win32Exception win32Exception = new Win32Exception(errorCode);
exception = new UnauthorizedAccessException(win32Exception.Message, win32Exception);
}
else if (errorCode == 32)
{
// Errorcode 32 is 'ERROR_SHARING_VIOLATION' i.e.
// The process cannot access the file because it is being used by another process.
// GetFileAttributes may return INVALID_FILE_ATTRIBUTES for a system file or directory because of this error.
// GetFileAttributes function tries to open the file with FILE_READ_ATTRIBUTES access right but it fails if the
// sharing flag for the file is set to 0x00000000.This flag prevents it from opening a file for delete, read, or
// write access. For example: C:\pagefile.sys is always opened by OS with sharing flag 0x00000000.
// But FindFirstFile is still able to get attributes as this api retrieves the required information using a find
// handle generated with FILE_LIST_DIRECTORY access.
// Fall back to FindFirstFile to check if the file actually exists.
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
NativeMethods.WIN32_FIND_DATA findData;
IntPtr findHandle = NativeMethods.FindFirstFile(path, out findData);
if (findHandle != INVALID_HANDLE_VALUE)
{
isDirectory = (findData.dwFileAttributes & NativeMethods.FileAttributes.Directory) != 0;
NativeMethods.FindClose(findHandle);
return true;
}
}
else if (errorCode == 53)
{
// ERROR_BAD_NETPATH - The network path was not found.
@@ -6991,6 +6991,26 @@ namespace Microsoft.PowerShell.Commands
Win32Exception win32Exception = new Win32Exception(errorCode);
throw new UnauthorizedAccessException(win32Exception.Message, win32Exception);
}
else if (errorCode == 32)
{
// Errorcode 32 is 'ERROR_SHARING_VIOLATION' i.e.
// The process cannot access the file because it is being used by another process.
// GetFileAttributes may return INVALID_FILE_ATTRIBUTES for a system file or directory because of this error.
// GetFileAttributes function tries to open the file with FILE_READ_ATTRIBUTES access right but it fails if the
// sharing flag for the file is set to 0x00000000.This flag prevents it from opening a file for delete, read, or
// write access. For example: C:\pagefile.sys is always opened by OS with sharing flag 0x00000000.
// But FindFirstFile is still able to get attributes as this api retrieves the required information using a find
// handle generated with FILE_LIST_DIRECTORY access.
// Fall back to FindFirstFile to check if the file actually exists.
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
Utils.NativeMethods.WIN32_FIND_DATA findData;
IntPtr findHandle = Utils.NativeMethods.FindFirstFile(path, out findData);
if (findHandle != INVALID_HANDLE_VALUE)
{
Utils.NativeMethods.FindClose(findHandle);
return (int)findData.dwFileAttributes;
}
}
}
return result;
@@ -2,6 +2,16 @@ Describe "Get-ChildItem" -Tags "CI" {
Context 'FileSystem provider' {
BeforeAll {
# Create Test data
$null = New-Item -Path $TestDrive -Name "a" -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name "B" -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name "c" -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name "D" -ItemType "File" -Force
$null = New-Item -Path $TestDrive -Name "E" -ItemType "Directory" -Force
$null = New-Item -Path $TestDrive -Name ".F" -ItemType "File" -Force | %{$_.Attributes = "hidden"}
}
It "Should list the contents of the current folder" {
(Get-ChildItem .).Name.Length | Should BeGreaterThan 0
}
@@ -23,12 +33,6 @@ Describe "Get-ChildItem" -Tags "CI" {
}
It "Should list files in sorted order" {
New-Item -Path $TestDrive -Name "a" -ItemType "File" -Force
New-Item -Path $TestDrive -Name "B" -ItemType "File" -Force
New-Item -Path $TestDrive -Name "c" -ItemType "File" -Force
New-Item -Path $TestDrive -Name "D" -ItemType "File" -Force
New-Item -Path $TestDrive -Name "E" -ItemType "Directory" -Force
$files = Get-ChildItem -Path $TestDrive
$files[0].Name | Should Be "E"
$files[1].Name | Should Be "a"
@@ -36,6 +40,26 @@ Describe "Get-ChildItem" -Tags "CI" {
$files[3].Name | Should Be "c"
$files[4].Name | Should Be "D"
}
It "Should list hidden files as well when 'Force' parameter is used" {
$files = Get-ChildItem -path $TestDrive -Force
$files | Should not be $null
$files.Count | Should be 6
$files.Name.Contains(".F")
}
It "Should list only hidden files when 'Hidden' parameter is used" {
$files = Get-ChildItem -path $TestDrive -Hidden
$files | Should not be $null
$files.Count | Should be 1
$files[0].Name | Should Be ".F"
}
It "Should give .sys file if the fullpath is specified with hidden and force parameter" -Skip:(!$IsWindows){
$file = Get-ChildItem -path "$env:SystemDrive\\pagefile.sys" -Hidden
$file | Should not be $null
$file.Count | Should be 1
$file.Name | Should be "pagefile.sys"
}
}
Context 'Env: Provider' {