-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Cleanup NativeItemExists() #6929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d364c67
01d2685
1637ad1
058ac67
286d714
4e941d6
b515681
5d85a4d
23e44ac
c6573fb
fdb1667
cf419bf
67c5d33
c37761a
0f25099
757d545
db25895
2c0fa8f
9098964
3963c46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -175,7 +175,7 @@ internal static List<string> GetModuleVersionsFromAbsolutePath(string directory) | |
| { | ||
| string moduleFile = Path.Combine(directory, fileName) + ext; | ||
|
|
||
| if (!Utils.NativeFileExists(moduleFile)) | ||
| if (!Utils.FileExists(moduleFile)) | ||
| { | ||
| continue; | ||
| } | ||
|
|
@@ -233,7 +233,7 @@ internal static IEnumerable<string> GetDefaultAvailableModuleFiles(string topDir | |
| foreach (string ext in ModuleIntrinsics.PSModuleExtensions) | ||
| { | ||
| string moduleFile = Path.Combine(directoryToCheck, proposedModuleName) + ext; | ||
| if (!Utils.NativeFileExists(moduleFile)) | ||
| if (!File.Exists(moduleFile)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Utils.FileExists behavior is the same (no exception is thrown). So it is better to use the standard method. Yes, we should review all these cases but there are dozens of them to do in this PR or in a new?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. let's do it in a separate PR. For this PR, just do the simple rename replacement: |
||
| { | ||
| continue; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -505,7 +505,7 @@ internal static bool IsValidPSEditionValue(string editionValue) | |
| T policy = null; | ||
| #if !UNIX | ||
| // On Windows, group policy settings from registry take precedence. | ||
| // If the requested policy is not defined in registry, we query the configuration file. | ||
| // If the requested policy is not defined in registry, we query the configuration file. | ||
| policy = GetPolicySettingFromGPO<T>(preferenceOrder); | ||
| if (policy != null) { return policy; } | ||
| #endif | ||
|
|
@@ -895,113 +895,57 @@ internal static bool IsAdministrator() | |
| #endif | ||
| } | ||
|
|
||
| internal static bool NativeItemExists(string path) | ||
| internal static bool ItemExists(string path) | ||
| { | ||
| bool unusedIsDirectory; | ||
| Exception unusedException; | ||
| try | ||
| { | ||
| return ItemExists(path, out bool _); | ||
| } | ||
| catch | ||
| { | ||
| } | ||
|
|
||
| return NativeItemExists(path, out unusedIsDirectory, out unusedException); | ||
| return false; | ||
| } | ||
|
|
||
| // This is done through P/Invoke since File.Exists and Directory.Exists pay 13% performance degradation | ||
| // through the CAS checks, and are terribly slow for network paths. | ||
| internal static bool NativeItemExists(string path, out bool isDirectory, out Exception exception) | ||
| internal static bool ItemExists(string path, out bool isDirectory) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, maybe changing this to
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll rename if we will not migrate to File.Exists/Directory.Exists in the PR. |
||
| { | ||
| exception = null; | ||
| isDirectory = false; | ||
|
|
||
| if (String.IsNullOrEmpty(path)) | ||
| { | ||
| isDirectory = false; | ||
| return false; | ||
| } | ||
| #if UNIX | ||
| isDirectory = Platform.NonWindowsIsDirectory(path); | ||
| return Platform.NonWindowsIsFile(path); | ||
| #else | ||
|
|
||
| if (IsReservedDeviceName(path)) | ||
| { | ||
| isDirectory = false; | ||
| return false; | ||
| } | ||
|
|
||
| int result = NativeMethods.GetFileAttributes(path); | ||
| if (result == -1) | ||
| try | ||
| { | ||
| int errorCode = Marshal.GetLastWin32Error(); | ||
| if (errorCode == 5) | ||
| { | ||
| // Handle "Access denied" specifically. | ||
| Win32Exception win32Exception = new Win32Exception(errorCode); | ||
| exception = new UnauthorizedAccessException(win32Exception.Message, win32Exception); | ||
| } | ||
| else if (errorCode == 32) | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same happens to
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please see the PR description (Fix is ready in CoreFX, we get it in 2.1.1.)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please see the PR description - we'll get the fix in .Net Core 2.1.1.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, so this will only affect
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Three files - pagefile.sys, hiberfil.sys, swapfile.sys. In the CoreFX PR a comment says that they can not emulate the behavior and so use the real file c:\pagefile.sys in test. I think users are unlikely to find something like this |
||
| // 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. | ||
| Win32Exception win32Exception = new Win32Exception(errorCode); | ||
| exception = new IOException(win32Exception.Message, win32Exception); | ||
| } | ||
| // Use 'File.GetAttributes()' because we want to get access exceptions. | ||
| FileAttributes attributes = File.GetAttributes(path); | ||
| isDirectory = attributes.HasFlag(FileAttributes.Directory); | ||
|
|
||
| isDirectory = false; | ||
| return (int)attributes != -1; | ||
| } | ||
| catch (IOException) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| isDirectory = (result & ((int)NativeMethods.FileAttributes.Directory)) == | ||
| ((int)NativeMethods.FileAttributes.Directory); | ||
|
|
||
| return true; | ||
| #endif | ||
| } | ||
|
|
||
| // This is done through P/Invoke since we pay 13% performance degradation | ||
| // through the CAS checks required by File.Exists and Directory.Exists | ||
| internal static bool NativeFileExists(string path) | ||
| internal static bool FileExists(string path) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think all uses of this method expects an exception to be thrown. Some uses might just believe that it's faster than I think you can inspect the uses of |
||
| { | ||
| bool isDirectory; | ||
| Exception ioException; | ||
|
|
||
| bool itemExists = NativeItemExists(path, out isDirectory, out ioException); | ||
| if (ioException != null) | ||
| { | ||
| throw ioException; | ||
| } | ||
| bool itemExists = ItemExists(path, out bool isDirectory); | ||
|
|
||
| return (itemExists && (!isDirectory)); | ||
| } | ||
|
|
||
| // This is done through P/Invoke since we pay 13% performance degradation | ||
| // through the CAS checks required by File.Exists and Directory.Exists | ||
| internal static bool NativeDirectoryExists(string path) | ||
| internal static bool DirectoryExists(string path) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should change the name of this one and I suggest rename them to
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll rename if we will not migrate to File.Exists/Directory.Exists in the PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, let's use a separate PR to do the migration changes. Go ahead rename this method. |
||
| { | ||
| bool isDirectory; | ||
| Exception ioException; | ||
|
|
||
| bool itemExists = NativeItemExists(path, out isDirectory, out ioException); | ||
| if (ioException != null) | ||
| { | ||
| throw ioException; | ||
| } | ||
| bool itemExists = ItemExists(path, out bool isDirectory); | ||
|
|
||
| return (itemExists && isDirectory); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use
Utils.FileExists?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Utils.FileExists behavior is the same (no exception is thrown). So it is better to use the standard method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to make all the
Utils.NativeFileExists -> File/Directory.Existschanges in a separate PR. So for now, just do the simple replacement ofUtils.NativeFileExists -> Utils.FileExists.