Created
July 16, 2015 22:18
-
-
Save kangaroo/d3b45edcb7e404633d2b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Win32; | |
using Microsoft.Win32.SafeHandles; | |
using System; | |
using System.Diagnostics.Contracts; | |
using System.Runtime.InteropServices; | |
using System.Security; | |
namespace System.IO | |
{ | |
/// <summary>Provides static methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of <see cref="T:System.IO.FileStream" /> objects.</summary> | |
/// <filterpriority>1</filterpriority> | |
[ComVisible(true)] | |
internal static class File | |
{ | |
private const int GetFileExInfoStandard = 0; | |
private const int ERROR_INVALID_PARAMETER = 87; | |
private const int ERROR_ACCESS_DENIED = 5; | |
[SecurityCritical] | |
internal static bool UnsafeExists(string path) | |
{ | |
return File.InternalExistsHelper(path, false); | |
} | |
[SecurityCritical] | |
private static bool InternalExistsHelper(string path, bool checkHost) | |
{ | |
try | |
{ | |
bool result; | |
if (path == null) | |
{ | |
result = false; | |
return result; | |
} | |
if (path.Length == 0) | |
{ | |
result = false; | |
return result; | |
} | |
path = Path.GetFullPathInternal(path); | |
Contract.Assert(path != null, "File.Exists: GetFullPathInternal returned null"); | |
if (path.Length > 0 && Path.IsDirectorySeparator(path[path.Length - 1])) | |
{ | |
result = false; | |
return result; | |
} | |
if (checkHost) | |
{ | |
FileSecurityState fileSecurityState = new FileSecurityState(FileSecurityStateAccess.Read, string.Empty, path); | |
fileSecurityState.EnsureState(); | |
} | |
result = File.InternalExists(path); | |
return result; | |
} | |
catch (ArgumentException) | |
{ | |
} | |
catch (NotSupportedException) | |
{ | |
} | |
catch (SecurityException) | |
{ | |
} | |
catch (IOException) | |
{ | |
} | |
catch (UnauthorizedAccessException) | |
{ | |
} | |
return false; | |
} | |
[SecurityCritical] | |
internal static bool InternalExists(string path) | |
{ | |
Win32Native.WIN32_FILE_ATTRIBUTE_DATA wIN32_FILE_ATTRIBUTE_DATA = default(Win32Native.WIN32_FILE_ATTRIBUTE_DATA); | |
return File.FillAttributeInfo(path, ref wIN32_FILE_ATTRIBUTE_DATA, false, true) == 0 && wIN32_FILE_ATTRIBUTE_DATA.fileAttributes != -1 && (wIN32_FILE_ATTRIBUTE_DATA.fileAttributes & 16) == 0; | |
} | |
[SecurityCritical] | |
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 wIN32_FIND_DATA = new Win32Native.WIN32_FIND_DATA(); | |
string fileName = path.TrimEnd(new char[] | |
{ | |
Path.DirectorySeparatorChar, | |
Path.AltDirectorySeparatorChar | |
}); | |
int errorMode = Win32Native.SetErrorMode(1); | |
try | |
{ | |
bool flag = false; | |
SafeFindHandle safeFindHandle = Win32Native.FindFirstFile(fileName, wIN32_FIND_DATA); | |
try | |
{ | |
if (safeFindHandle.IsInvalid) | |
{ | |
flag = true; | |
num = Marshal.GetLastWin32Error(); | |
if ((num == 2 || num == 3 || num == 21) && !returnErrorOnNotFound) | |
{ | |
num = 0; | |
data.fileAttributes = -1; | |
} | |
return num; | |
} | |
} | |
finally | |
{ | |
try | |
{ | |
safeFindHandle.Close(); | |
} | |
catch | |
{ | |
if (!flag) | |
{ | |
Contract.Assert(false, "File::FillAttributeInfo - FindClose failed!"); | |
__Error.WinIOError(); | |
} | |
} | |
} | |
} | |
finally | |
{ | |
Win32Native.SetErrorMode(errorMode); | |
} | |
data.PopulateFrom(wIN32_FIND_DATA); | |
return num; | |
} | |
bool flag2 = false; | |
int errorMode2 = Win32Native.SetErrorMode(1); | |
try | |
{ | |
flag2 = Win32Native.GetFileAttributesEx(path, 0, ref data); | |
} | |
finally | |
{ | |
Win32Native.SetErrorMode(errorMode2); | |
} | |
if (!flag2) | |
{ | |
num = Marshal.GetLastWin32Error(); | |
if (num != 2 && num != 3 && num != 21) | |
{ | |
return File.FillAttributeInfo(path, ref data, true, returnErrorOnNotFound); | |
} | |
if (!returnErrorOnNotFound) | |
{ | |
num = 0; | |
data.fileAttributes = -1; | |
} | |
} | |
return num; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment