Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Montoya <zamont@microsoft.com>2017-05-19 04:26:06 +0300
committerZach Montoya <zamont@microsoft.com>2017-05-19 04:26:06 +0300
commit8a7d06f4ce18cb78d322ff679e0b930dc07c78fe (patch)
tree49f301d62bc1e30b1a0ef94cb3591b3427bb0ca1
parent3dfdee07d87a6d2bef24b66a1a033fa53eb3318f (diff)
Enable file-based ResourceManager by implementing the method FileBasedResourceGroveler.FindResourceFile.
Implementing File.Exists brought in the majority of the changes, which includes the added structs, attributes, and native calls to KERNEL32. The majority of these additions were copied straight from CoreFX. Note: On Unix, this File.Exists implementation throws NotImplementedException. Types/Methods added: shared/ - Interop.Kernel32.FileAttributes - Interop.Kernel32.FindClose - Interop.Kernel32.FindFirstFile - Interop.Kernel32.GetFileAttributesEx src/ - Microsoft.Win32.SafeHandles.SafeFindHandle - System.IO.File (for internal use) - System.Runtime.InteropServices.BestFitMappingAttribute (relocated from S.P.Interop) [tfs-changeset: 1658849]
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs17
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs16
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs43
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs94
-rw-r--r--src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems6
-rw-r--r--src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs32
-rw-r--r--src/System.Private.CoreLib/src/System.Private.CoreLib.csproj5
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.Unix.cs14
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.Windows.cs136
-rw-r--r--src/System.Private.CoreLib/src/System/IO/File.cs47
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs (renamed from src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs)4
-rw-r--r--src/System.Private.Interop/src/System.Private.Interop.csproj1
-rw-r--r--src/System.Private.Interop/src/TypeForwarders.cs3
15 files changed, 412 insertions, 14 deletions
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs
new file mode 100644
index 000000000..725a25a71
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ internal partial class FileAttributes
+ {
+ internal const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
+ internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
+ internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
+ internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs
new file mode 100644
index 000000000..03d8c8b32
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, SetLastError = true)]
+ internal extern static bool FindClose(IntPtr hFindFile);
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs
new file mode 100644
index 000000000..80b1ddd28
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use FindFirstFile.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)]
+ private static extern SafeFindHandle FindFirstFileExPrivate(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags);
+
+ internal static SafeFindHandle FindFirstFile(string fileName, ref WIN32_FIND_DATA data)
+ {
+ fileName = PathInternal.EnsureExtendedPrefixOverMaxPath(fileName);
+
+ // use FindExInfoBasic since we don't care about short name and it has better perf
+ return FindFirstFileExPrivate(fileName, FINDEX_INFO_LEVELS.FindExInfoBasic, ref data, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, 0);
+ }
+
+ internal enum FINDEX_INFO_LEVELS : uint
+ {
+ FindExInfoStandard = 0x0u,
+ FindExInfoBasic = 0x1u,
+ FindExInfoMaxInfoLevel = 0x2u,
+ }
+
+ internal enum FINDEX_SEARCH_OPS : uint
+ {
+ FindExSearchNameMatch = 0x0u,
+ FindExSearchLimitToDirectories = 0x1u,
+ FindExSearchLimitToDevices = 0x2u,
+ FindExSearchMaxSearchOp = 0x3u,
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
new file mode 100644
index 000000000..4cce56bd0
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode)]
+ private static extern bool GetFileAttributesExPrivate(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
+
+ internal static bool GetFileAttributesEx(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation)
+ {
+ name = PathInternal.EnsureExtendedPrefixOverMaxPath(name);
+ return GetFileAttributesExPrivate(name, fileInfoLevel, ref lpFileInformation);
+ }
+
+ internal enum GET_FILEEX_INFO_LEVELS : uint
+ {
+ GetFileExInfoStandard = 0x0u,
+ GetFileExMaxInfoLevel = 0x1u,
+ }
+
+ internal struct WIN32_FILE_ATTRIBUTE_DATA
+ {
+ internal int fileAttributes;
+ internal uint ftCreationTimeLow;
+ internal uint ftCreationTimeHigh;
+ internal uint ftLastAccessTimeLow;
+ internal uint ftLastAccessTimeHigh;
+ internal uint ftLastWriteTimeLow;
+ internal uint ftLastWriteTimeHigh;
+ internal uint fileSizeHigh;
+ internal uint fileSizeLow;
+
+ internal void PopulateFrom(ref WIN32_FIND_DATA findData)
+ {
+ // Copy the information to data
+ fileAttributes = (int)findData.dwFileAttributes;
+ ftCreationTimeLow = findData.ftCreationTime.dwLowDateTime;
+ ftCreationTimeHigh = findData.ftCreationTime.dwHighDateTime;
+ ftLastAccessTimeLow = findData.ftLastAccessTime.dwLowDateTime;
+ ftLastAccessTimeHigh = findData.ftLastAccessTime.dwHighDateTime;
+ ftLastWriteTimeLow = findData.ftLastWriteTime.dwLowDateTime;
+ ftLastWriteTimeHigh = findData.ftLastWriteTime.dwHighDateTime;
+ fileSizeHigh = findData.nFileSizeHigh;
+ fileSizeLow = findData.nFileSizeLow;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ [BestFitMapping(false)]
+ internal unsafe struct WIN32_FIND_DATA
+ {
+ internal uint dwFileAttributes;
+ internal FILE_TIME ftCreationTime;
+ internal FILE_TIME ftLastAccessTime;
+ internal FILE_TIME ftLastWriteTime;
+ internal uint nFileSizeHigh;
+ internal uint nFileSizeLow;
+ internal uint dwReserved0;
+ internal uint dwReserved1;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ internal string cFileName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+ internal string cAlternateFileName;
+ }
+
+ internal struct FILE_TIME
+ {
+ internal uint dwLowDateTime;
+ internal uint dwHighDateTime;
+
+ internal FILE_TIME(long fileTime)
+ {
+ dwLowDateTime = (uint)fileTime;
+ dwHighDateTime = (uint)(fileTime >> 32);
+ }
+
+ internal long ToTicks()
+ {
+ return ((long)dwHighDateTime << 32) + dwLowDateTime;
+ }
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
index 981d35811..ae98a97c7 100644
--- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
@@ -472,11 +472,15 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CloseHandle.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile.cs" Condition="'$(IsProjectNLibrary)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile2.cs" Condition="'$(IsProjectNLibrary)' == 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FileAttributes.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FILE_INFO_BY_HANDLE_CLASS.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FileTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FindClose.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FindFirstFileEx.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FlushFileBuffers.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FormatMessage.cs"/>
- <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCPInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCPInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileAttributesEx.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileInformationByHandleEx.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileType_SafeHandle.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFullPathNameW.cs"/>
diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
new file mode 100644
index 000000000..1c30841da
--- /dev/null
+++ b/src/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+**
+** A wrapper for find handles
+**
+**
+===========================================================*/
+
+using System;
+using System.Security;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using Microsoft.Win32;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ internal SafeFindHandle() : base(true) { }
+
+ override protected bool ReleaseHandle()
+ {
+ return Interop.Kernel32.FindClose(handle);
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index c080ce9d6..98d415d1f 100644
--- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -136,6 +136,7 @@
<Compile Include="Internal\Threading\Tasks\Tracing\TaskTrace.cs" />
<Compile Include="Interop\Interop.manual.cs" />
<Compile Include="Interop\Interop.WinRT.cs" Condition="'$(EnableWinRT)' == 'true'" />
+ <Compile Include="Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
<Compile Include="Microsoft\Win32\SafeHandles\SafeWaitHandle.cs" />
<Compile Include="System\Runtime\CompilerServices\CastableObject.cs" />
<Compile Include="System\Reflection\AssemblyNameHelpers.StrongName.cs" />
@@ -214,6 +215,9 @@
<Compile Include="System\InvokeUtils.cs" />
<Compile Include="System\IO\BinaryReader.cs" />
<Compile Include="System\IO\BinaryWriter.cs" />
+ <Compile Include="System\IO\File.cs" />
+ <Compile Include="System\IO\File.Windows.cs" Condition="'$(TargetsWindows)'=='true'" />
+ <Compile Include="System\IO\File.Unix.cs" Condition="'$(TargetsUnix)'=='true'" />
<Compile Include="System\IO\FileLoadException.CoreRT.cs" />
<Compile Include="System\IO\IOException.cs" />
<Compile Include="System\IO\MemoryStream.cs" />
@@ -298,6 +302,7 @@
<Compile Include="System\Runtime\GcSettings.cs" />
<Compile Include="System\Runtime\TypeLoaderExports.cs" />
<Compile Include="System\Runtime\InitializeFinalizerThread.cs" />
+ <Compile Include="System\Runtime\InteropServices\BestFitMappingAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\DllImportAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\GCHandle.cs" />
<Compile Include="System\Runtime\InteropServices\GCHandleType.cs" />
diff --git a/src/System.Private.CoreLib/src/System/IO/File.Unix.cs b/src/System.Private.CoreLib/src/System/IO/File.Unix.cs
new file mode 100644
index 000000000..3cf5bf836
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.Unix.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(String path)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/IO/File.Windows.cs b/src/System.Private.CoreLib/src/System/IO/File.Windows.cs
new file mode 100644
index 000000000..4bd8e9426
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.Windows.cs
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(String path)
+ {
+ Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = new Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA();
+ int errorCode = FillAttributeInfo(path, ref data, false, true);
+
+ return (errorCode == 0) && (data.fileAttributes != -1)
+ && ((data.fileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0);
+ }
+
+ // 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 Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
+ {
+ int errorCode = 0;
+ if (tryagain) // someone has a handle to the file open, or other error
+ {
+ Interop.Kernel32.WIN32_FIND_DATA findData;
+ findData = new Interop.Kernel32.WIN32_FIND_DATA();
+
+ // Remove trailing 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.
+ // SetThreadErrorMode will let us disable this, but we should set the error
+ // mode back, since this may have wide-ranging effects.
+ uint oldMode;
+ bool setThreadErrorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
+ try
+ {
+ bool error = false;
+ SafeFindHandle handle = Interop.Kernel32.FindFirstFile(tempPath, ref findData);
+ try
+ {
+ if (handle.IsInvalid)
+ {
+ error = true;
+ errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND ||
+ errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND ||
+ errorCode == Interop.Errors.ERROR_NOT_READY) // floppy device not ready
+ {
+ if (!returnErrorOnNotFound)
+ {
+ // Return default value for backward compatibility
+ errorCode = 0;
+ data.fileAttributes = -1;
+ }
+ }
+ return errorCode;
+ }
+ }
+ finally
+ {
+ // Close the Win32 handle
+ try
+ {
+ handle.Dispose();
+ }
+ catch
+ {
+ // if we're already returning an error, don't throw another one.
+ if (!error)
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (setThreadErrorModeSuccess)
+ Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
+ }
+
+ // Copy the information to data
+ data.PopulateFrom(ref findData);
+ }
+ 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.
+ // SetThreadErrorMode will let us disable this, but we should set the error
+ // mode back, since this may have wide-ranging effects.
+ bool success = false;
+ uint oldMode;
+ bool setThreadErrorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
+ try
+ {
+ success = Interop.Kernel32.GetFileAttributesEx(path, Interop.Kernel32.GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, ref data);
+ }
+ finally
+ {
+ if (setThreadErrorModeSuccess)
+ Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
+ }
+
+ if (!success)
+ {
+ errorCode = Marshal.GetLastWin32Error();
+ if (errorCode != Interop.Errors.ERROR_FILE_NOT_FOUND &&
+ errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND &&
+ errorCode != Interop.Errors.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 compatibility
+ errorCode = 0;
+ data.fileAttributes = -1;
+ }
+ }
+ }
+ }
+
+ return errorCode;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/IO/File.cs b/src/System.Private.CoreLib/src/System/IO/File.cs
new file mode 100644
index 000000000..30513c894
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/IO/File.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Security;
+
+namespace System.IO
+{
+ internal static partial class File
+ {
+ // Tests if a file exists. The result is true if the file
+ // given by the specified path exists; otherwise, the result is
+ // false. Note that if path describes a directory,
+ // Exists will return true.
+ public static bool Exists(String path)
+ {
+ try
+ {
+ if (path == null)
+ return false;
+ if (path.Length == 0)
+ return false;
+
+ path = Path.GetFullPath(path);
+
+ // After normalizing, check whether path ends in directory separator.
+ // Otherwise, FillAttributeInfo removes it and we may return a false positive.
+ // GetFullPath should never return null
+ Debug.Assert(path != null, "File.Exists: GetFullPath returned null");
+ if (path.Length > 0 && PathInternal.IsDirectorySeparator(path[path.Length - 1]))
+ {
+ return false;
+ }
+
+ return InternalExists(path);
+ }
+ catch (ArgumentException) { }
+ catch (NotSupportedException) { } // Security can throw this on ":"
+ catch (SecurityException) { }
+ catch (IOException) { }
+ catch (UnauthorizedAccessException) { }
+
+ return false;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
index fb48cec1c..07353f4b6 100644
--- a/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
+++ b/src/System.Private.CoreLib/src/System/Resources/FileBasedResourceGroveler.cs
@@ -82,9 +82,6 @@ namespace System.Resources
private String FindResourceFile(CultureInfo culture, String fileName)
{
- throw new NotImplementedException();
- // todo remove the throw and ifdef when File and FileStream are in CoreLib
-#if FILE_TYPES_IN_CORELIB
Debug.Assert(culture != null, "culture shouldn't be null; check caller");
Debug.Assert(fileName != null, "fileName shouldn't be null; check caller");
@@ -104,7 +101,6 @@ namespace System.Resources
return fileName;
return null; // give up.
-#endif // FILE_TYPES_IN_CORELIB
}
// Constructs a new ResourceSet for a given file name. The logic in
diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
index db078c714..7bf3e3d2c 100644
--- a/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
+++ b/src/System.Private.CoreLib/src/System/Resources/ResourceReader.cs
@@ -108,9 +108,6 @@ namespace System.Resources
public ResourceReader(String fileName)
{
- throw new NotImplementedException();
-#if FILE_TYPES_IN_CORELIB
- // todo remove the throw and ifdef when File and FileStream are in CoreLib
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
_store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8);
@@ -123,7 +120,6 @@ namespace System.Resources
_store.Dispose(); // If we threw an exception, close the file.
throw;
}
-#endif // FILE_TYPES_IN_CORELIB
}
public ResourceReader(Stream stream)
diff --git a/src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
index e73e64998..a880c62e6 100644
--- a/src/System.Private.Interop/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/BestFitMappingAttribute.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
@@ -19,4 +17,4 @@ namespace System.Runtime.InteropServices
public bool BestFitMapping { get { return _bestFitMapping; } }
public bool ThrowOnUnmappableChar;
}
-}
+} \ No newline at end of file
diff --git a/src/System.Private.Interop/src/System.Private.Interop.csproj b/src/System.Private.Interop/src/System.Private.Interop.csproj
index 607c33957..431cc60e2 100644
--- a/src/System.Private.Interop/src/System.Private.Interop.csproj
+++ b/src/System.Private.Interop/src/System.Private.Interop.csproj
@@ -87,7 +87,6 @@
<ItemGroup>
<Compile Include="System\Runtime\InteropServices\AllowReversePInvokeCallsAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\ArrayWithOffset.cs" />
- <Compile Include="System\Runtime\InteropServices\BestFitMappingAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\BStrWrapper.cs" />
<Compile Include="System\Runtime\InteropServices\ClassInterfaceAttribute.cs" />
<Compile Include="System\Runtime\InteropServices\ClassInterfaceType.cs" />
diff --git a/src/System.Private.Interop/src/TypeForwarders.cs b/src/System.Private.Interop/src/TypeForwarders.cs
index b9e6dd0da..badf60477 100644
--- a/src/System.Private.Interop/src/TypeForwarders.cs
+++ b/src/System.Private.Interop/src/TypeForwarders.cs
@@ -10,4 +10,5 @@
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.InAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.DllNotFoundException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.EntryPointNotFoundException))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.MarshalDirectiveException))] \ No newline at end of file
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.MarshalDirectiveException))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Runtime.InteropServices.BestFitMappingAttribute))] \ No newline at end of file