Skip to content

Instantly share code, notes, and snippets.

@kangaroo
Created July 16, 2015 22:18
Show Gist options
  • Save kangaroo/d3b45edcb7e404633d2b to your computer and use it in GitHub Desktop.
Save kangaroo/d3b45edcb7e404633d2b to your computer and use it in GitHub Desktop.
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