public void Dispose() { if (null != hFindFile) { hFindFile.Close(); } }
/// <summary> /// Get file attributes /// </summary> /// <param name="path">Path to file or folder</param> /// <param name="data">The file attribute structure to fill</param> /// <param name="tryagain">If false try get file attributes with GetFileAttributesEx function. If true try with the FindFirstFile function.</param> internal static void FillAttributeInfo(string path, ref WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain = false) { int num; if (tryagain) { WIN32_FIND_DATA win_find_data = new WIN32_FIND_DATA(); string fileName = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); int num2 = SafeNativeMethods.SetErrorMode(1); try { SafeFindHandle handle = SafeNativeMethods.FindFirstFile(fileName, win_find_data); try { if (handle.IsInvalid) { num = Marshal.GetLastWin32Error(); if (num != 0) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } } finally { handle.Close(); } } finally { _ = SafeNativeMethods.SetErrorMode(num2); } data.PopulateFrom(win_find_data); return; } bool flag2 = false; int newMode = SafeNativeMethods.SetErrorMode(1); try { flag2 = SafeNativeMethods.GetFileAttributesEx(path, 0, ref data); } finally { _ = SafeNativeMethods.SetErrorMode(newMode); } if (!flag2) { num = Marshal.GetLastWin32Error(); if (((num != 2) && (num != 3)) && (num != 0x15)) { FillAttributeInfo(path, ref data, true); //return; } //else if (num == 2) //return; //else if (num != 0) //throw new Win32Exception(num); //return; } }
/// <summary> /// Returns a file (PathTooLong safe, volume guid safe). /// </summary> public static WIN32_FILE GetFile(string path) { WIN32_FIND_DATA data = new WIN32_FIND_DATA(); SafeFindHandle sfh = FindFirstFile(FixPathBackwards(path), data); if (sfh == null || sfh.IsInvalid || sfh.IsClosed) { throw new Exception(new Win32Exception(Marshal.GetLastWin32Error()).Message); } if (!sfh.IsInvalid && !sfh.IsClosed) { sfh.Close(); } sfh = null; return(new WIN32_FILE(path, data)); }
public static IEnumerable <LittleFileInfo> GetFiles(string folderPath) { WIN32_FIND_DATA win_find_data = new WIN32_FIND_DATA(); string prefixedfolderPath = folderPath.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); if (!prefixedfolderPath.StartsWith("\\\\", StringComparison.Ordinal)) { prefixedfolderPath = string.Concat("\\\\?\\", prefixedfolderPath); } int num2 = SafeNativeMethods.SetErrorMode(1); try { SafeFindHandle handle = SafeNativeMethods.FindFirstFile(prefixedfolderPath + @"\*", win_find_data); try { if (handle.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } else { bool found = true; while (found) { if (win_find_data.cFileName != "." && win_find_data.cFileName != "..") { WIN32_FILE_ATTRIBUTE_DATA data = new WIN32_FILE_ATTRIBUTE_DATA(); data.PopulateFrom(win_find_data); yield return(new LittleFileInfo(folderPath, win_find_data.cFileName, data)); } found = SafeNativeMethods.FindNextFile(handle, win_find_data); } } } finally { handle.Close(); } } finally { _ = SafeNativeMethods.SetErrorMode(num2); } }
// Returns 0 on success, otherwise a Win32 error code. Note that // classes should use -1 as the uninitialized state for dataInitialized. internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound) { int dataInitialised = 0; if (tryagain) // someone has a handle to the file open, or other error { Win32Native.WIN32_FIND_DATA findData; findData = new Win32Native.WIN32_FIND_DATA(); // Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error String tempPath = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); #if !PLATFORM_UNIX // For floppy drives, normally the OS will pop up a dialog saying // there is no disk in drive A:, please insert one. We don't want that. // SetThreadErrorMode will let us disable this, but we should set the error // mode back, since this may have wide-ranging effects. uint oldMode; bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode); try { #endif bool error = false; SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, findData); try { if (handle.IsInvalid) { error = true; dataInitialised = Marshal.GetLastWin32Error(); if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND || dataInitialised == Win32Native.ERROR_PATH_NOT_FOUND || dataInitialised == Win32Native.ERROR_NOT_READY) // floppy device not ready { if (!returnErrorOnNotFound) { // Return default value for backward compatibility dataInitialised = 0; data.fileAttributes = -1; } } return(dataInitialised); } } finally { // Close the Win32 handle try { handle.Close(); } catch { // if we're already returning an error, don't throw another one. if (!error) { Debug.Assert(false, "File::FillAttributeInfo - FindClose failed!"); throw Win32Marshal.GetExceptionForLastWin32Error(); } } } #if !PLATFORM_UNIX } finally { if (errorModeSuccess) { Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); } } #endif // Copy the information to data data.PopulateFrom(findData); } else { bool success = false; #if !PLATFORM_UNIX // For floppy drives, normally the OS will pop up a dialog saying // there is no disk in drive A:, please insert one. We don't want that. // SetThreadErrorMode will let us disable this, but we should set the error // mode back, since this may have wide-ranging effects. uint oldMode; bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode); try { #endif success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data); #if !PLATFORM_UNIX } finally { if (errorModeSuccess) { Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); } } #endif if (!success) { dataInitialised = Marshal.GetLastWin32Error(); if (dataInitialised != Win32Native.ERROR_FILE_NOT_FOUND && dataInitialised != Win32Native.ERROR_PATH_NOT_FOUND && dataInitialised != Win32Native.ERROR_NOT_READY) // floppy device not ready { // In case someone latched onto the file. Take the perf hit only for failure return(FillAttributeInfo(path, ref data, true, returnErrorOnNotFound)); } else { if (!returnErrorOnNotFound) { // Return default value for backward compbatibility dataInitialised = 0; data.fileAttributes = -1; } } } } return(dataInitialised); }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException"> /// The collection was modified after the enumerator was created. /// </exception> public bool MoveNext() { bool retval = false; //If the handle is null, this is first call to MoveNext in the current // directory. In that case, start a new search. if (m_currentContext.SubdirectoriesToProcess == null) { if (m_hndFindFile == null) { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, m_path).Demand(); string searchPath = Path.Combine(m_path, m_filter); m_hndFindFile = FindFirstFile(searchPath, m_win_find_data); retval = !m_hndFindFile.IsInvalid; } else { //Otherwise, find the next item. retval = FindNextFile(m_hndFindFile, m_win_find_data); } } //If the call to FindNextFile or FindFirstFile succeeded... if (retval) { if (((FileAttributes)m_win_find_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { //Ignore folders for now. We call MoveNext recursively here to // move to the next item that FindNextFile will return. return(MoveNext()); } } else if (m_searchOption == SearchOption.AllDirectories) { //SearchContext context = new SearchContext(m_hndFindFile, m_path); //m_contextStack.Push(context); //m_path = Path.Combine(m_path, m_win_find_data.cFileName); //m_hndFindFile = null; if (m_currentContext.SubdirectoriesToProcess == null) { string[] subDirectories = Directory.GetDirectories(m_path); m_currentContext.SubdirectoriesToProcess = new Stack <string>(subDirectories); } if (m_currentContext.SubdirectoriesToProcess.Count > 0) { string subDir = m_currentContext.SubdirectoriesToProcess.Pop(); m_contextStack.Push(m_currentContext); m_path = subDir; m_hndFindFile = null; m_currentContext = new SearchContext(m_path); return(MoveNext()); } //If there are no more files in this directory and we are // in a sub directory, pop back up to the parent directory and // continue the search from there. if (m_contextStack.Count > 0) { m_currentContext = m_contextStack.Pop(); m_path = m_currentContext.Path; if (m_hndFindFile != null) { m_hndFindFile.Close(); m_hndFindFile = null; } return(MoveNext()); } } return(retval); }
/// <summary> /// Get an enumerator that returns all of the files that match the wildcards that /// are in any of the directories to be searched. /// </summary> /// <returns> An IEnumerable that returns all matching files one by one. </returns> /// <remarks> /// The enumerator that is returned finds files using a lazy algorithm that /// searches directories incrementally as matches are consumed. /// </remarks> public IEnumerable <FileInfo> Matches() { foreach (string rootPath in m_paths) { string path = rootPath.Trim(); // we "recurse" into a new directory by jumping to this spot top: // check security - ensure that caller has rights to read this directory new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Path.Combine(path, ".")).Demand(); // now that security is checked, go read the directory FindData findData = new FindData(); SafeFindHandle handle = SafeNativeMethods.FindFirstFile(Path.Combine(path, "*"), findData); m_scopes.Push(new SearchInfo(handle, path)); bool restart = false; // we "return" from a sub-directory by jumping to this spot restart: // ReSharper disable InvertIf if (!handle.IsInvalid) { // ReSharper restore InvertIf do { // if we restarted the loop (unwound a recursion), fetch the next match if (restart) { restart = false; continue; } // don't match . or .. if (findData.fileName.Equals(@".") || findData.fileName.Equals(@"..")) { continue; } if ((findData.fileAttributes & (int)FileAttributes.Directory) != 0) { if (m_includeSubDirs) { // it's a directory - recurse into it path = Path.Combine(path, findData.fileName); goto top; } } else { // it's a file, see if any of the filespecs matches it foreach (Regex fileSpec in m_fileSpecs) { // if this spec matches, return this file's info if (fileSpec.IsMatch(findData.fileName)) { yield return(new FileInfo(Path.Combine(path, findData.fileName))); } } } } while (SafeNativeMethods.FindNextFile(handle, findData)); // close this find handle handle.Close(); // unwind the stack - are we still in a recursion? m_scopes.Pop(); if (m_scopes.Count > 0) { SearchInfo si = m_scopes.Peek(); handle = si.Handle; path = si.Path; restart = true; goto restart; } } } }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException"> /// The collection was modified after the enumerator was created. /// </exception> public bool MoveNext() { while (true) { var retval = false; //If the handle is null, this is first call to MoveNext in the current // directory. In that case, start a new search. if (_currentContext.SubdirectoriesToProcess == null) { if (_hndFindFile == null) { var searchPath = Path.Combine(_path, _filter); _hndFindFile = FindFirstFile(searchPath, _winFindData, _largeBuffer); retval = !_hndFindFile.IsInvalid; } else { //Otherwise, find the next item. retval = FindNextFile(_hndFindFile, _winFindData); } } //If the call to FindNextFile or FindFirstFile succeeded... if (retval) { if ((_winFindData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { continue; } } else if (_searchOption == SearchOption.AllDirectories) { //SearchContext context = new SearchContext(_hndFindFile, _path); //_contextStack.Push(context); //_path = PathResolve.Combine(_path, _win_find_data.cFileName); //_hndFindFile = null; if (_currentContext.SubdirectoriesToProcess == null) { try { var subDirectories = Directory.GetDirectories(_path); _currentContext.SubdirectoriesToProcess = new Stack <string>(subDirectories); } catch (UnauthorizedAccessException) { _currentContext.SubdirectoriesToProcess = new Stack <string>(); } } if (_currentContext.SubdirectoriesToProcess.Count > 0) { var subDir = _currentContext.SubdirectoriesToProcess.Pop(); _contextStack.Push(_currentContext); _path = subDir; _hndFindFile = null; _currentContext = new SearchContext(_path); continue; } //If there are no more files in this directory and we are // in a sub directory, pop back up to the parent directory and // continue the search from there. if (_contextStack.Count > 0) { _currentContext = _contextStack.Pop(); _path = _currentContext.Path; if (_hndFindFile != null) { _hndFindFile.Close(); _hndFindFile = null; } continue; } } return(retval); } }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException"> /// The collection was modified after the enumerator was created. /// </exception> public bool MoveNext() { bool retval = false; //If the handle is null, this is first call to MoveNext in the current // directory. In that case, start a new search. if (m_currentContext.SubdirectoriesToProcess == null) { if (m_hndFindFile == null) { //new FileIOPermission(FileIOPermissionAccess.PathDiscovery, m_path).Demand(); string searchPath = Path.Combine(m_path, m_filter); // m_hndFindFile = FindFirstFile(searchPath, m_win_find_data); m_hndFindFile = FindFirstFileEx(searchPath, FINDEX_INFO_LEVELS.FindExInfoStandard, m_win_find_data, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, FIND_FIRST_EX.LargeFetch); m_wasteDirectories.Clear(); retval = !m_hndFindFile.IsInvalid; } else { //Otherwise, find the next item. retval = FindNextFile(m_hndFindFile, m_win_find_data); } } else { int tmp = 0; } //If the call to FindNextFile or FindFirstFile succeeded... if (retval) { while (((FileAttributes)m_win_find_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory && retval) { if (m_win_find_data.cFileName != "." && m_win_find_data.cFileName != "..") { m_wasteDirectories.Push(m_win_find_data.cFileName); return(retval); } retval = FindNextFile(m_hndFindFile, m_win_find_data); } if (retval) { return(retval); } return(MoveNext()); } else if (m_searchOption == SearchOption.AllDirectories) { if (retval || m_hndFindFile == null || !m_hndFindFile.IsInvalid) { if (m_depth <= MAX_DEPTH - 1 || MAX_DEPTH == -1) { if (m_currentContext.SubdirectoriesToProcess == null) { //string[] subDirectories = Directory.GetDirectories(m_path); //m_currentContext.SubdirectoriesToProcess = new Stack<string>(subDirectories); m_currentContext.SubdirectoriesToProcess = new Stack <string>(m_wasteDirectories); } if (m_currentContext.SubdirectoriesToProcess.Count > 0) { string subDir = m_currentContext.SubdirectoriesToProcess.Pop(); m_depth++; m_contextStack.Push(m_currentContext); m_path = Path.Combine(m_path, subDir); m_hndFindFile = null; m_currentContext = new SearchContext(m_path); return(MoveNext()); } } } //If there are no more files in this directory and we are // in a sub directory, pop back up to the parent directory and // continue the search from there. if (m_contextStack.Count > 0) { m_depth--; m_currentContext = m_contextStack.Pop(); m_path = m_currentContext.Path; if (m_hndFindFile != null) { m_hndFindFile.Close(); m_hndFindFile = null; } return(MoveNext()); } } return(retval); }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException"> /// The collection was modified after the enumerator was created. /// </exception> public bool MoveNext() { bool retval = false; //If the handle is null, this is first call to MoveNext in the current // directory. In that case, start a new search. if (m_currentContext.SubdirectoriesToProcess == null) { if (m_hndFindFile == null) { string searchPath = Path.Combine(m_path, m_filter); m_hndFindFile = FindFirstFile(searchPath, m_win_find_data); retval = !m_hndFindFile.IsInvalid; } else { if (subDirectoryCount < subDirectoryLimit) { retval = FindNextFile(m_hndFindFile, m_win_find_data); subDirectoryCount++; } } } //If the call to FindNextFile or FindFirstFile succeeded... if (retval) { if (((FileAttributes)m_win_find_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { //Ignore folders for now. We call MoveNext recursively here to // move to the next item that FindNextFile will return. return(MoveNext()); } } else if (m_searchOption == SearchOption.AllDirectories) { subDirectoryLimit = 0; //SearchContext context = new SearchContext(m_hndFindFile, m_path); //m_contextStack.Push(context); //m_path = Path.Combine(m_path, m_win_find_data.cFileName); //m_hndFindFile = null; if (m_currentContext.SubdirectoriesToProcess == null) { string[] subDirectories = null; try { subDirectories = Directory.EnumerateDirectories(m_path).AsParallel().ToArray(); } catch (UnauthorizedAccessException) { } if (subDirectories != null) { m_currentContext.SubdirectoriesToProcess = new Stack <string>(subDirectories); } else { m_currentContext.SubdirectoriesToProcess = new Stack <string>(); } } if (m_currentContext.SubdirectoriesToProcess.Count > 0) { string subDir = m_currentContext.SubdirectoriesToProcess.Pop(); m_contextStack.Push(m_currentContext); m_path = subDir; m_hndFindFile = null; m_currentContext = new SearchContext(m_path); return(MoveNext()); } //If there are no more files in this directory and we are // in a sub directory, pop back up to the parent directory and // continue the search from there. if (m_contextStack.Count > 0) { m_currentContext = m_contextStack.Pop(); m_path = m_currentContext.Path; if (m_hndFindFile != null) { m_hndFindFile.Close(); m_hndFindFile = null; } return(MoveNext()); } } return(retval); }
internal static int FillAttributeInfo(string path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound) { int num = 0; if (tryagain) { Win32Native.WIN32_FIND_DATA win_find_data = new Win32Native.WIN32_FIND_DATA(); string fileName = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); int num2 = Win32Native.SetErrorMode(1); try { bool flag = false; SafeFindHandle handle = Win32Native.FindFirstFile(fileName, win_find_data); try { if (handle.IsInvalid) { flag = true; num = Marshal.GetLastWin32Error(); if ((((num == 2) || (num == 3)) || (num == 0x15)) && !returnErrorOnNotFound) { num = 0; data.fileAttributes = -1; } return(num); } } finally { try { handle.Close(); } catch { if (!flag) { __Error.WinIOError(); } } } } finally { Win32Native.SetErrorMode(num2); } data.PopulateFrom(win_find_data); return(num); } bool flag2 = false; int newMode = Win32Native.SetErrorMode(1); try { flag2 = Win32Native.GetFileAttributesEx(path, 0, ref data); } finally { Win32Native.SetErrorMode(newMode); } if (!flag2) { num = Marshal.GetLastWin32Error(); if (((num != 2) && (num != 3)) && (num != 0x15)) { return(FillAttributeInfo(path, ref data, true, returnErrorOnNotFound)); } if (!returnErrorOnNotFound) { num = 0; data.fileAttributes = -1; } } return(num); }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; /// false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException"> /// The collection was modified after the enumerator was created. /// </exception> public bool MoveNext() { bool retval = false; //If the handle is null, this is first call to MoveNext in the current // directory. In that case, start a new search. if (m_currentContext.currPhase != 2) { if (m_hndFindFile == null) { //new FileIOPermission(FileIOPermissionAccess.PathDiscovery, m_path).Demand(); string searchPath = Path.Combine(m_path, m_filter); if (searchPath.Length > 256) { searchPath = searchPath.StartsWith(@"\\") ? @"\\?\UNC" + searchPath.Substring(1) : @"\\?\" + searchPath; } m_hndFindFile = FindFirstFileW(searchPath, m_win_find_data); retval = !m_hndFindFile.IsInvalid; } else { //Otherwise, find the next item. retval = FindNextFileW(m_hndFindFile, m_win_find_data); } } m_currentContext.currPhase = retval ? 1 : 2; //If the call to FindNextFile or FindFirstFile succeeded... if (retval) { // skip . and .. if (m_win_find_data.cFileName == "." || m_win_find_data.cFileName == "..") { return(MoveNext()); } // save subdirectory to scan later if (m_searchOption == SearchOption.AllDirectories && ((FileAttributes)m_win_find_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { m_currentContext.SubdirectoriesToProcess.Push(m_path); } } else if (m_searchOption == SearchOption.AllDirectories) { //SearchContext context = new SearchContext(m_hndFindFile, m_path); //m_contextStack.Push(context); //m_path = Path.Combine(m_path, m_win_find_data.cFileName); //m_hndFindFile = null; if (m_currentContext.SubdirectoriesToProcess.Count > 0) { string subDir = m_currentContext.SubdirectoriesToProcess.Pop(); m_contextStack.Push(m_currentContext); m_path = subDir; m_hndFindFile = null; m_currentContext = new SearchContext(m_path); return(MoveNext()); } //If there are no more files in this directory and we are // in a sub directory, pop back up to the parent directory and // continue the search from there. if (m_contextStack.Count > 0) { m_currentContext = m_contextStack.Pop(); m_path = m_currentContext.Path; if (m_hndFindFile != null) { m_hndFindFile.Close(); m_hndFindFile = null; } return(MoveNext()); } } return(retval); }
internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound) { int dataInitialised = 0; if (tryagain) // someone has a handle to the file open, or other error { Win32Native.WIN32_FIND_DATA win95data; // We do this only on Win95 machines win95data = new Win32Native.WIN32_FIND_DATA(); // Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error String tempPath = path.TrimEnd(new char [] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); // For floppy drives, normally the OS will pop up a dialog saying // there is no disk in drive A:, please insert one. We don't want that. // SetErrorMode will let us disable this, but we should set the error // mode back, since this may have wide-ranging effects. int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); try { bool error = false; SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, win95data); try { if (handle.IsInvalid) { error = true; dataInitialised = Marshal.GetLastWin32Error(); if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND || dataInitialised == Win32Native.ERROR_PATH_NOT_FOUND || dataInitialised == Win32Native.ERROR_NOT_READY) // floppy device not ready { if (!returnErrorOnNotFound) { // Return default value for backward compbatibility dataInitialised = 0; data.fileAttributes = -1; } } return(dataInitialised); } } finally { // Close the Win32 handle try { handle.Close(); } catch { // if we're already returning an error, don't throw another one. if (!error) { BCLDebug.Assert(false, "File::FillAttributeInfo - FindClose failed!"); __Error.WinIOError(); } } } } finally { Win32Native.SetErrorMode(oldMode); } // Copy the information to data data.fileAttributes = win95data.dwFileAttributes; data.ftCreationTimeLow = (uint)win95data.ftCreationTime_dwLowDateTime; data.ftCreationTimeHigh = (uint)win95data.ftCreationTime_dwHighDateTime; data.ftLastAccessTimeLow = (uint)win95data.ftLastAccessTime_dwLowDateTime; data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime; data.ftLastWriteTimeLow = (uint)win95data.ftLastWriteTime_dwLowDateTime; data.ftLastWriteTimeHigh = (uint)win95data.ftLastWriteTime_dwHighDateTime; data.fileSizeHigh = win95data.nFileSizeHigh; data.fileSizeLow = win95data.nFileSizeLow; } else { // For floppy drives, normally the OS will pop up a dialog saying // there is no disk in drive A:, please insert one. We don't want that. // SetErrorMode will let us disable this, but we should set the error // mode back, since this may have wide-ranging effects. bool success = false; int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS); try { success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data); } finally { Win32Native.SetErrorMode(oldMode); } if (!success) { dataInitialised = Marshal.GetLastWin32Error(); if (dataInitialised != Win32Native.ERROR_FILE_NOT_FOUND && dataInitialised != Win32Native.ERROR_PATH_NOT_FOUND && dataInitialised != Win32Native.ERROR_NOT_READY) // floppy device not ready { // In case someone latched onto the file. Take the perf hit only for failure return(FillAttributeInfo(path, ref data, true, returnErrorOnNotFound)); } else { if (!returnErrorOnNotFound) { // Return default value for backward compbatibility dataInitialised = 0; data.fileAttributes = -1; } } } } return(dataInitialised); }