private static bool FileOrDirectoryExists(FileArtifactType fileArtifactType, string path) { // The path gets normalized so we always use backslashes path = NormalizePathToWindowsStyle(path); WindowsNative.Win32FindData findResult; using (var findHandle = WindowsNative.FindFirstFileW(path.TrimEnd('\\'), out findResult)) { // Any error is interpreted as a file not found. This matches the managed Directory.Exists and File.Exists behavior if (findHandle.IsInvalid) { return(false); } if (fileArtifactType == FileArtifactType.FileOrDirectory) { return(true); } var isDirectory = (findResult.DwFileAttributes & FileAttributes.Directory) != 0; return(!(fileArtifactType == FileArtifactType.Directory ^ isDirectory)); } }
private static WindowsNative.EnumerateDirectoryResult CustomEnumerateDirectoryEntries( string directoryPath, FileArtifactType fileArtifactType, string pattern, SearchOption searchOption, ICollection <string> result) { var searchDirectoryPath = Path.Combine(directoryPath.TrimEnd('\\'), "*"); WindowsNative.Win32FindData findResult; using (var findHandle = WindowsNative.FindFirstFileW(searchDirectoryPath, out findResult)) { if (findHandle.IsInvalid) { int hr = Marshal.GetLastWin32Error(); Debug.Assert(hr != WindowsNative.ErrorFileNotFound); WindowsNative.EnumerateDirectoryStatus findHandleOpenStatus; switch (hr) { case WindowsNative.ErrorFileNotFound: findHandleOpenStatus = WindowsNative.EnumerateDirectoryStatus.SearchDirectoryNotFound; break; case WindowsNative.ErrorPathNotFound: findHandleOpenStatus = WindowsNative.EnumerateDirectoryStatus.SearchDirectoryNotFound; break; case WindowsNative.ErrorDirectory: findHandleOpenStatus = WindowsNative.EnumerateDirectoryStatus.CannotEnumerateFile; break; case WindowsNative.ErrorAccessDenied: findHandleOpenStatus = WindowsNative.EnumerateDirectoryStatus.AccessDenied; break; default: findHandleOpenStatus = WindowsNative.EnumerateDirectoryStatus.UnknownError; break; } return(new WindowsNative.EnumerateDirectoryResult(directoryPath, findHandleOpenStatus, hr)); } while (true) { var isDirectory = (findResult.DwFileAttributes & FileAttributes.Directory) != 0; // There will be entries for the current and parent directories. Ignore those. if (!isDirectory || (findResult.CFileName != "." && findResult.CFileName != "..")) { // Make sure pattern and directory/file filters are honored // We special case the "*" pattern since it is the default when no pattern is specified // so we avoid calling the matching function if (pattern == "*" || WindowsNative.PathMatchSpecExW(findResult.CFileName, pattern, WindowsNative.DwFlags.PmsfNormal) == WindowsNative.ErrorSuccess) { if (fileArtifactType == FileArtifactType.FileOrDirectory || !(fileArtifactType == FileArtifactType.Directory ^ isDirectory)) { result.Add(Path.Combine(directoryPath, findResult.CFileName)); } } // Recursively go into subfolders if specified if (searchOption == SearchOption.AllDirectories && isDirectory) { var recurs = CustomEnumerateDirectoryEntries( Path.Combine(directoryPath, findResult.CFileName), fileArtifactType, pattern, searchOption, result); if (!recurs.Succeeded) { return(recurs); } } } if (!WindowsNative.FindNextFileW(findHandle, out findResult)) { int hr = Marshal.GetLastWin32Error(); if (hr == WindowsNative.ErrorNoMoreFiles) { // Graceful completion of enumeration. return(new WindowsNative.EnumerateDirectoryResult( directoryPath, WindowsNative.EnumerateDirectoryStatus.Success, hr)); } Debug.Assert(hr != WindowsNative.ErrorSuccess); return(new WindowsNative.EnumerateDirectoryResult( directoryPath, WindowsNative.EnumerateDirectoryStatus.UnknownError, hr)); } } } }
/// <nodoc/> protected override bool ReleaseHandle() { return(WindowsNative.FindClose(handle)); }