summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2018-01-29 15:22:01 -0800
committerGitHub <noreply@github.com>2018-01-29 15:22:01 -0800
commitb29f6328510207970763580d6f4db864e4b198af (patch)
tree3ce16eef93b0db5bcb72617bdb15e4e185c760f6
parentb02961001f1978437f7bd5ba7c6d9a2c3da3c088 (diff)
downloadcoreclr-b29f6328510207970763580d6f4db864e4b198af.tar.gz
coreclr-b29f6328510207970763580d6f4db864e4b198af.tar.bz2
coreclr-b29f6328510207970763580d6f4db864e4b198af.zip
Move TimeZoneInfo.Unix.cs to shared CoreLib partition (#16057)
- Refactored internal version of System.IO.File to be similar to full corefx version - Cleaned up some Unix PAL APIs that are no longer used Contributes to dotnet/corert#5248
-rw-r--r--src/dlls/mscoree/mscorwks_unixexports.src36
-rw-r--r--src/mscorlib/System.Private.CoreLib.csproj5
-rw-r--r--src/mscorlib/shared/Internal/IO/File.Unix.cs25
-rw-r--r--src/mscorlib/shared/Internal/IO/File.Windows.cs77
-rw-r--r--src/mscorlib/shared/Internal/IO/File.cs77
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs102
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs4
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs26
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFindHandle.Windows.cs (renamed from src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs)12
-rw-r--r--src/mscorlib/shared/System.Private.CoreLib.Shared.projitems7
-rw-r--r--src/mscorlib/shared/System/TimeZoneInfo.Unix.cs (renamed from src/mscorlib/src/System/TimeZoneInfo.Unix.cs)85
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryKey.cs14
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs2
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Win32Native.cs158
-rw-r--r--src/mscorlib/src/System/Environment.cs10
-rw-r--r--src/mscorlib/src/System/IO/Directory.cs84
-rw-r--r--src/mscorlib/src/System/IO/File.cs234
-rw-r--r--src/mscorlib/src/System/IO/FileSystemEnumerable.cs628
-rw-r--r--src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs22
-rw-r--r--src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs2
-rw-r--r--src/mscorlib/src/System/Threading/EventWaitHandle.cs14
-rw-r--r--src/mscorlib/src/System/Threading/Mutex.cs10
-rw-r--r--src/mscorlib/src/System/Threading/Semaphore.cs14
23 files changed, 442 insertions, 1206 deletions
diff --git a/src/dlls/mscoree/mscorwks_unixexports.src b/src/dlls/mscoree/mscorwks_unixexports.src
index a3ca37c3f2..0eae53f3f9 100644
--- a/src/dlls/mscoree/mscorwks_unixexports.src
+++ b/src/dlls/mscoree/mscorwks_unixexports.src
@@ -23,87 +23,51 @@ GetCLRRuntimeHost
; Win32 API and other PAL functions used by the mscorlib
CloseHandle
CoCreateGuid
-CopyFileW
CoTaskMemAlloc
CoTaskMemRealloc
CoTaskMemFree
-CreateDirectoryW
CreateEventW
CreateEventExW
-CreateFileW
CreateMutexW
CreateMutexExW
CreateSemaphoreW
CreateSemaphoreExW
-DeleteFileW
DuplicateHandle
-FindClose
-FindFirstFileW
-FindNextFileW
-FlushFileBuffers
FormatMessageW
FreeEnvironmentStringsW
GetACP
-GetConsoleOutputCP
-GetCurrentDirectoryW
-GetCurrentProcess
GetCurrentProcessId
GetCurrentThreadId
GetEnvironmentStringsW
GetEnvironmentVariableW
-GetFileAttributesExW
-GetFileSize
-GetFullPathNameW
-GetLongPathNameW
GetProcAddress
-GetProcessAffinityMask
GetStdHandle
GetSystemInfo
-GetTempFileNameW
-GetTempPathW
LocalAlloc
LocalReAlloc
LocalFree
lstrlenA
lstrlenW
-MapViewOfFile
MetaDataGetDispenser
-MoveFileExW
MultiByteToWideChar
OpenEventW
OpenMutexW
OpenSemaphoreW
OutputDebugStringW
-PAL_Random
QueryPerformanceCounter
QueryPerformanceFrequency
RaiseException
-ReadFile
ReleaseMutex
ReleaseSemaphore
-RemoveDirectoryW
ResetEvent
-SetCurrentDirectoryW
-SetEndOfFile
SetEnvironmentVariableW
-SetErrorMode
SetEvent
-SetFileAttributesW
-SetFilePointer
SysAllocStringLen
SysFreeString
SysStringLen
-UnmapViewOfFile
VirtualAlloc
VirtualFree
GlobalMemoryStatusEx
VirtualQuery
WideCharToMultiByte
WriteFile
-GetLogicalProcessorInformationEx
-SetThreadGroupAffinity
-SetThreadAffinityMask
-GetThreadGroupAffinity
-GetCurrentProcessorNumberEx
-SetThreadIdealProcessorEx
-
diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj
index 707dcee489..a85e2988c7 100644
--- a/src/mscorlib/System.Private.CoreLib.csproj
+++ b/src/mscorlib/System.Private.CoreLib.csproj
@@ -500,9 +500,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\IO\BinaryReader.cs" />
- <Compile Include="$(BclSourcesRoot)\System\IO\Directory.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\SearchOption.cs" />
- <Compile Include="$(BclSourcesRoot)\System\IO\File.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\FileLoadException.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
@@ -573,7 +571,6 @@
<Compile Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentQueue.cs" />
</ItemGroup>
<ItemGroup>
- <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
<Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeWaitHandle.cs" />
<Compile Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
</ItemGroup>
@@ -587,10 +584,8 @@
<Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.Unix.cs" />
- <Compile Include="$(BclSourcesRoot)\System\IO\FileSystemEnumerable.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.Unix.cs" />
- <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="$(BclSourcesRoot)\Interop\Windows\Kernel32\Interop.GetSystemDirectoryW.cs" />
diff --git a/src/mscorlib/shared/Internal/IO/File.Unix.cs b/src/mscorlib/shared/Internal/IO/File.Unix.cs
new file mode 100644
index 0000000000..50fa0f0d0c
--- /dev/null
+++ b/src/mscorlib/shared/Internal/IO/File.Unix.cs
@@ -0,0 +1,25 @@
+// 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 Internal.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(string fullPath)
+ {
+ Interop.Sys.FileStatus fileinfo;
+
+ // First use stat, as we want to follow symlinks. If that fails, it could be because the symlink
+ // is broken, we don't have permissions, etc., in which case fall back to using LStat to evaluate
+ // based on the symlink itself.
+ if (Interop.Sys.Stat(fullPath, out fileinfo) < 0 &&
+ Interop.Sys.LStat(fullPath, out fileinfo) < 0)
+ {
+ return false;
+ }
+
+ return ((fileinfo.Mode & Interop.Sys.FileTypes.S_IFMT) != Interop.Sys.FileTypes.S_IFDIR);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Internal/IO/File.Windows.cs b/src/mscorlib/shared/Internal/IO/File.Windows.cs
new file mode 100644
index 0000000000..0acae3b457
--- /dev/null
+++ b/src/mscorlib/shared/Internal/IO/File.Windows.cs
@@ -0,0 +1,77 @@
+// 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.IO;
+using System.Runtime.InteropServices;
+
+namespace Internal.IO
+{
+ internal static partial class File
+ {
+ internal static bool InternalExists(string fullPath)
+ {
+ Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data = new Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA();
+ int errorCode = FillAttributeInfo(fullPath, ref data, returnErrorOnNotFound: true);
+
+ return (errorCode == 0) && (data.dwFileAttributes != -1)
+ && ((data.dwFileAttributes & Interop.Kernel32.FileAttributes.FILE_ATTRIBUTE_DIRECTORY) == 0);
+ }
+
+ /// <summary>
+ /// Returns 0 on success, otherwise a Win32 error code. Note that
+ /// classes should use -1 as the uninitialized state for dataInitialized.
+ /// </summary>
+ /// <param name="returnErrorOnNotFound">Return the error code for not found errors?</param>
+ internal static int FillAttributeInfo(string path, ref Interop.Kernel32.WIN32_FILE_ATTRIBUTE_DATA data, bool returnErrorOnNotFound)
+ {
+ int errorCode = Interop.Errors.ERROR_SUCCESS;
+
+ using (DisableMediaInsertionPrompt.Create())
+ {
+ if (!Interop.Kernel32.GetFileAttributesEx(path, Interop.Kernel32.GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, ref data))
+ {
+ errorCode = Marshal.GetLastWin32Error();
+ if (errorCode == Interop.Errors.ERROR_ACCESS_DENIED)
+ {
+ // Files that are marked for deletion will not let you GetFileAttributes,
+ // ERROR_ACCESS_DENIED is given back without filling out the data struct.
+ // FindFirstFile, however, will. Historically we always gave back attributes
+ // for marked-for-deletion files.
+
+ var findData = new Interop.Kernel32.WIN32_FIND_DATA();
+ using (SafeFindHandle handle = Interop.Kernel32.FindFirstFile(path, ref findData))
+ {
+ if (handle.IsInvalid)
+ {
+ errorCode = Marshal.GetLastWin32Error();
+ }
+ else
+ {
+ errorCode = Interop.Errors.ERROR_SUCCESS;
+ data.PopulateFrom(ref findData);
+ }
+ }
+ }
+ }
+ }
+
+ if (errorCode != Interop.Errors.ERROR_SUCCESS && !returnErrorOnNotFound)
+ {
+ switch (errorCode)
+ {
+ case Interop.Errors.ERROR_FILE_NOT_FOUND:
+ case Interop.Errors.ERROR_PATH_NOT_FOUND:
+ case Interop.Errors.ERROR_NOT_READY: // Removable media not ready
+ // Return default value for backward compatibility
+ data.dwFileAttributes = -1;
+ return Interop.Errors.ERROR_SUCCESS;
+ }
+ }
+
+ return errorCode;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Internal/IO/File.cs b/src/mscorlib/shared/Internal/IO/File.cs
new file mode 100644
index 0000000000..2fcc0f391f
--- /dev/null
+++ b/src/mscorlib/shared/Internal/IO/File.cs
@@ -0,0 +1,77 @@
+// 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;
+using System.Diagnostics;
+using System.Security;
+using System.IO;
+
+namespace Internal.IO
+{
+ //
+ // Subsetted clone of System.IO.File for internal runtime use.
+ // Keep in sync with https://github.com/dotnet/corefx/tree/master/src/System.IO.FileSystem.
+ //
+ 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;
+ }
+
+ public static byte[] ReadAllBytes(string path)
+ {
+ // bufferSize == 1 used to avoid unnecessary buffer in FileStream
+ using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1))
+ {
+ long fileLength = fs.Length;
+ if (fileLength > int.MaxValue)
+ throw new IOException(SR.IO_FileTooLong2GB);
+
+ int index = 0;
+ int count = (int)fileLength;
+ byte[] bytes = new byte[count];
+ while (count > 0)
+ {
+ int n = fs.Read(bytes, index, count);
+ if (n == 0)
+ throw Error.GetEndOfFile();
+ index += n;
+ count -= n;
+ }
+ return bytes;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs
new file mode 100644
index 0000000000..d98c4285c0
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs
@@ -0,0 +1,102 @@
+// 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;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ private static readonly int s_readBufferSize = GetReadDirRBufferSize();
+
+ internal enum NodeType : int
+ {
+ DT_UNKNOWN = 0,
+ DT_FIFO = 1,
+ DT_CHR = 2,
+ DT_DIR = 4,
+ DT_BLK = 6,
+ DT_REG = 8,
+ DT_LNK = 10,
+ DT_SOCK = 12,
+ DT_WHT = 14
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private unsafe struct InternalDirectoryEntry
+ {
+ internal IntPtr Name;
+ internal int NameLength;
+ internal NodeType InodeType;
+ }
+
+ internal struct DirectoryEntry
+ {
+ internal NodeType InodeType;
+ internal string InodeName;
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_OpenDir", SetLastError = true)]
+ internal static extern Microsoft.Win32.SafeHandles.SafeDirectoryHandle OpenDir(string path);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetReadDirRBufferSize", SetLastError = false)]
+ internal static extern int GetReadDirRBufferSize();
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ReadDirR", SetLastError = false)]
+ private static extern unsafe int ReadDirR(IntPtr dir, byte* buffer, int bufferSize, out InternalDirectoryEntry outputEntry);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_CloseDir", SetLastError = true)]
+ internal static extern int CloseDir(IntPtr dir);
+
+ // The calling pattern for ReadDir is described in src/Native/System.Native/pal_readdir.cpp
+ internal static int ReadDir(SafeDirectoryHandle dir, out DirectoryEntry outputEntry)
+ {
+ bool addedRef = false;
+ try
+ {
+ // We avoid a native string copy into InternalDirectoryEntry.
+ // - If the platform suppors reading into a buffer, the data is read directly into the buffer. The
+ // data can be read as long as the buffer is valid.
+ // - If the platform does not support reading into a buffer, the information returned in
+ // InternalDirectoryEntry points to native memory owned by the SafeDirectoryHandle. The data is only
+ // valid until the next call to CloseDir/ReadDir. We extend the reference until we have copied all data
+ // to ensure it does not become invalid by a CloseDir; and we copy the data so our caller does not
+ // use the native memory held by the SafeDirectoryHandle.
+ dir.DangerousAddRef(ref addedRef);
+
+ unsafe
+ {
+ // s_readBufferSize is zero when the native implementation does not support reading into a buffer.
+ byte* buffer = stackalloc byte[s_readBufferSize];
+ InternalDirectoryEntry temp;
+ int ret = ReadDirR(dir.DangerousGetHandle(), buffer, s_readBufferSize, out temp);
+ // We copy data into DirectoryEntry to ensure there are no dangling references.
+ outputEntry = ret == 0 ?
+ new DirectoryEntry() { InodeName = GetDirectoryEntryName(temp), InodeType = temp.InodeType } :
+ default(DirectoryEntry);
+
+ return ret;
+ }
+ }
+ finally
+ {
+ if (addedRef)
+ {
+ dir.DangerousRelease();
+ }
+ }
+ }
+
+ private static unsafe string GetDirectoryEntryName(InternalDirectoryEntry dirEnt)
+ {
+ if (dirEnt.NameLength == -1)
+ return Marshal.PtrToStringAnsi(dirEnt.Name);
+ else
+ return Marshal.PtrToStringAnsi(dirEnt.Name, dirEnt.NameLength);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
index 4cce56bd05..181fb10105 100644
--- a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
@@ -31,7 +31,7 @@ internal partial class Interop
internal struct WIN32_FILE_ATTRIBUTE_DATA
{
- internal int fileAttributes;
+ internal int dwFileAttributes;
internal uint ftCreationTimeLow;
internal uint ftCreationTimeHigh;
internal uint ftLastAccessTimeLow;
@@ -44,7 +44,7 @@ internal partial class Interop
internal void PopulateFrom(ref WIN32_FIND_DATA findData)
{
// Copy the information to data
- fileAttributes = (int)findData.dwFileAttributes;
+ dwFileAttributes = (int)findData.dwFileAttributes;
ftCreationTimeLow = findData.ftCreationTime.dwLowDateTime;
ftCreationTimeHigh = findData.ftCreationTime.dwHighDateTime;
ftLastAccessTimeLow = findData.ftLastAccessTime.dwLowDateTime;
diff --git a/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs
new file mode 100644
index 0000000000..f7435eaae1
--- /dev/null
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs
@@ -0,0 +1,26 @@
+// 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;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ internal sealed class SafeDirectoryHandle : SafeHandle
+ {
+ private SafeDirectoryHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ return Interop.Sys.CloseDir(handle) == 0;
+ }
+
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFindHandle.Windows.cs
index d7d833d35d..4ba05409fd 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFindHandle.Windows.cs
@@ -2,20 +2,10 @@
// 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
@@ -26,7 +16,7 @@ namespace Microsoft.Win32.SafeHandles
override protected bool ReleaseHandle()
{
- return Win32Native.FindClose(handle);
+ return Interop.Kernel32.FindClose(handle);
}
}
}
diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
index 89d7cfd039..ec576aa835 100644
--- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
@@ -19,6 +19,7 @@
</Compile>
</ItemDefinitionGroup>
<ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)Internal\IO\File.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Internal\Runtime\CompilerServices\Unsafe.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleMinusOneIsInvalid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleZeroOrMinusOneIsInvalid.cs" />
@@ -663,7 +664,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysAllocStringLen.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysFreeString.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysStringLen.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Internal\IO\File.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFindHandle.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Windows.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Windows.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.Win32.cs" Condition="'$(EnableWinRT)' != 'true' and '$(EnableDummyGlobalizationImplementation)' != 'true'" />
@@ -735,11 +738,14 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Permissions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.PosixFAdvise.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Read.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.ReadDir.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.ReadLink.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Stat.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.SysLog.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Unlink.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Write.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Internal\IO\File.Unix.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeDirectoryHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Debug.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Unix.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
@@ -756,5 +762,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Unix.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Unix.cs" />
</ItemGroup>
</Project>
diff --git a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs b/src/mscorlib/shared/System/TimeZoneInfo.Unix.cs
index 49260931ac..2f7830fc19 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs
+++ b/src/mscorlib/shared/System/TimeZoneInfo.Unix.cs
@@ -10,6 +10,8 @@ using System.Text;
using System.Threading;
using System.Security;
+using Internal.IO;
+
namespace System
{
public sealed partial class TimeZoneInfo
@@ -396,6 +398,87 @@ namespace System
}
/// <summary>
+ /// Enumerate files
+ /// </summary>
+ private static IEnumerable<string> EnumerateFilesRecursively(string path)
+ {
+ List<string> toExplore = null; // List used as a stack
+
+ string currentPath = path;
+ for(;;)
+ {
+ using (Microsoft.Win32.SafeHandles.SafeDirectoryHandle dirHandle = Interop.Sys.OpenDir(currentPath))
+ {
+ if (dirHandle.IsInvalid)
+ {
+ throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), currentPath, isDirectory: true);
+ }
+
+ // Read each entry from the enumerator
+ Interop.Sys.DirectoryEntry dirent;
+ while (Interop.Sys.ReadDir(dirHandle, out dirent) == 0)
+ {
+ if (dirent.InodeName == "." || dirent.InodeName == "..")
+ continue;
+
+ string fullPath = Path.Combine(currentPath, dirent.InodeName);
+
+ // Get from the dir entry whether the entry is a file or directory.
+ // We classify everything as a file unless we know it to be a directory.
+ bool isDir;
+ if (dirent.InodeType == Interop.Sys.NodeType.DT_DIR)
+ {
+ // We know it's a directory.
+ isDir = true;
+ }
+ else if (dirent.InodeType == Interop.Sys.NodeType.DT_LNK || dirent.InodeType == Interop.Sys.NodeType.DT_UNKNOWN)
+ {
+ // It's a symlink or unknown: stat to it to see if we can resolve it to a directory.
+ // If we can't (e.g. symlink to a file, broken symlink, etc.), we'll just treat it as a file.
+
+ Interop.Sys.FileStatus fileinfo;
+ if (Interop.Sys.Stat(fullPath, out fileinfo) >= 0)
+ {
+ isDir = (fileinfo.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR;
+ }
+ else
+ {
+ isDir = false;
+ }
+ }
+ else
+ {
+ // Otherwise, treat it as a file. This includes regular files, FIFOs, etc.
+ isDir = false;
+ }
+
+ // Yield the result if the user has asked for it. In the case of directories,
+ // always explore it by pushing it onto the stack, regardless of whether
+ // we're returning directories.
+ if (isDir)
+ {
+ if (toExplore == null)
+ {
+ toExplore = new List<string>();
+ }
+ toExplore.Add(fullPath);
+ }
+ else
+ {
+ yield return fullPath;
+ }
+ }
+ }
+
+ if (toExplore == null || toExplore.Count == 0)
+ break;
+
+ currentPath = toExplore[toExplore.Count - 1];
+ toExplore.RemoveAt(toExplore.Count - 1);
+ }
+ }
+
+ /// <summary>
/// Find the time zone id by searching all the tzfiles for the one that matches rawData
/// and return its file name.
/// </summary>
@@ -410,7 +493,7 @@ namespace System
try
{
- foreach (string filePath in Directory.EnumerateFiles(timeZoneDirectory, "*", SearchOption.AllDirectories))
+ foreach (string filePath in EnumerateFilesRecursively(timeZoneDirectory))
{
// skip the localtime and posixrules file, since they won't give us the correct id
if (!string.Equals(filePath, localtimeFilePath, StringComparison.OrdinalIgnoreCase)
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
index 350880e52f..5087f271e5 100644
--- a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
+++ b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
@@ -205,7 +205,7 @@ namespace Microsoft.Win32
// From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE
// This still means the name doesn't exist. We need to be consistent with previous OS.
//
- if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE)
+ if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND || errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE)
{
if (throwOnMissingValue)
{
@@ -287,7 +287,7 @@ namespace Microsoft.Win32
}
// Return null if we didn't find the key.
- if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL)
+ if (ret == Interop.Errors.ERROR_ACCESS_DENIED || ret == Interop.Errors.ERROR_BAD_IMPERSONATION_LEVEL)
{
// We need to throw SecurityException here for compatibility reasons,
// although UnauthorizedAccessException will make more sense.
@@ -503,7 +503,7 @@ namespace Microsoft.Win32
int r;
byte[] blob = new byte[size];
- while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput)))
+ while (Interop.Errors.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput)))
{
if (size == Int32.MaxValue)
{
@@ -531,7 +531,7 @@ namespace Microsoft.Win32
// For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data).
// Some OS's returned ERROR_MORE_DATA even in success cases, so we
// want to continue on through the function.
- if (ret != Win32Native.ERROR_MORE_DATA)
+ if (ret != Interop.Errors.ERROR_MORE_DATA)
return data;
}
}
@@ -960,13 +960,13 @@ namespace Microsoft.Win32
{
switch (errorCode)
{
- case Win32Native.ERROR_ACCESS_DENIED:
+ case Interop.Errors.ERROR_ACCESS_DENIED:
if (str != null)
throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_RegistryKeyGeneric_Key, str));
else
throw new UnauthorizedAccessException();
- case Win32Native.ERROR_INVALID_HANDLE:
+ case Interop.Errors.ERROR_INVALID_HANDLE:
/**
* For normal RegistryKey instances we dispose the SafeRegHandle and throw IOException.
* However, for HKEY_PERFORMANCE_DATA (on a local or remote machine) we avoid disposing the
@@ -986,7 +986,7 @@ namespace Microsoft.Win32
}
goto default;
- case Win32Native.ERROR_FILE_NOT_FOUND:
+ case Interop.Errors.ERROR_FILE_NOT_FOUND:
throw new IOException(SR.Arg_RegKeyNotFound, errorCode);
default:
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
index 1338596ba6..b69bc42e64 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
@@ -29,7 +29,7 @@ namespace Microsoft.Win32.SafeHandles
override protected bool ReleaseHandle()
{
- return (RegCloseKey(handle) == Win32Native.ERROR_SUCCESS);
+ return (RegCloseKey(handle) == Interop.Errors.ERROR_SUCCESS);
}
[DllImport(Win32Native.ADVAPI32)]
diff --git a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
index a6b28dba00..fbb1b35132 100644
--- a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
@@ -215,34 +215,6 @@ namespace Microsoft.Win32
}
[StructLayout(LayoutKind.Sequential)]
- 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 int fileSizeHigh;
- internal int fileSizeLow;
-
- internal void PopulateFrom(WIN32_FIND_DATA findData)
- {
- // Copy the information to data
- fileAttributes = 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)]
internal struct MEMORYSTATUSEX
{
// The length field must be set to the size of this data structure.
@@ -374,28 +346,6 @@ namespace Microsoft.Win32
[DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle); // param is NOT a handle, but it returns one!
- // From WinBase.h
- internal const int FILE_TYPE_DISK = 0x0001;
- internal const int FILE_TYPE_CHAR = 0x0002;
- internal const int FILE_TYPE_PIPE = 0x0003;
-
- internal const int REPLACEFILE_WRITE_THROUGH = 0x1;
- internal const int REPLACEFILE_IGNORE_MERGE_ERRORS = 0x2;
-
- private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
- private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
- private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
-
- internal const uint FILE_MAP_WRITE = 0x0002;
- internal const uint FILE_MAP_READ = 0x0004;
-
- // Constants from WinNT.h
- internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
- internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
- internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
-
- internal const int IO_REPARSE_TAG_MOUNT_POINT = unchecked((int)0xA0000003);
-
internal const int PAGE_READWRITE = 0x04;
internal const int MEM_COMMIT = 0x1000;
@@ -403,114 +353,6 @@ namespace Microsoft.Win32
internal const int MEM_RELEASE = 0x8000;
internal const int MEM_FREE = 0x10000;
- // Error codes from WinError.h
- internal const int ERROR_SUCCESS = 0x0;
- internal const int ERROR_INVALID_FUNCTION = 0x1;
- internal const int ERROR_FILE_NOT_FOUND = 0x2;
- internal const int ERROR_PATH_NOT_FOUND = 0x3;
- internal const int ERROR_ACCESS_DENIED = 0x5;
- internal const int ERROR_INVALID_HANDLE = 0x6;
- internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
- internal const int ERROR_INVALID_DATA = 0xd;
- internal const int ERROR_INVALID_DRIVE = 0xf;
- internal const int ERROR_NO_MORE_FILES = 0x12;
- internal const int ERROR_NOT_READY = 0x15;
- internal const int ERROR_BAD_LENGTH = 0x18;
- internal const int ERROR_SHARING_VIOLATION = 0x20;
- internal const int ERROR_NOT_SUPPORTED = 0x32;
- internal const int ERROR_FILE_EXISTS = 0x50;
- internal const int ERROR_INVALID_PARAMETER = 0x57;
- internal const int ERROR_BROKEN_PIPE = 0x6D;
- internal const int ERROR_CALL_NOT_IMPLEMENTED = 0x78;
- internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
- internal const int ERROR_INVALID_NAME = 0x7B;
- internal const int ERROR_BAD_PATHNAME = 0xA1;
- internal const int ERROR_ALREADY_EXISTS = 0xB7;
- internal const int ERROR_ENVVAR_NOT_FOUND = 0xCB;
- internal const int ERROR_FILENAME_EXCED_RANGE = 0xCE; // filename too long.
- internal const int ERROR_NO_DATA = 0xE8;
- internal const int ERROR_PIPE_NOT_CONNECTED = 0xE9;
- internal const int ERROR_MORE_DATA = 0xEA;
- internal const int ERROR_DIRECTORY = 0x10B;
- internal const int ERROR_OPERATION_ABORTED = 0x3E3; // 995; For IO Cancellation
- internal const int ERROR_NOT_FOUND = 0x490; // 1168; For IO Cancellation
- internal const int ERROR_NO_TOKEN = 0x3f0;
- internal const int ERROR_DLL_INIT_FAILED = 0x45A;
- internal const int ERROR_NON_ACCOUNT_SID = 0x4E9;
- internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;
- internal const int ERROR_UNKNOWN_REVISION = 0x519;
- internal const int ERROR_INVALID_OWNER = 0x51B;
- internal const int ERROR_INVALID_PRIMARY_GROUP = 0x51C;
- internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521;
- internal const int ERROR_PRIVILEGE_NOT_HELD = 0x522;
- internal const int ERROR_NONE_MAPPED = 0x534;
- internal const int ERROR_INVALID_ACL = 0x538;
- internal const int ERROR_INVALID_SID = 0x539;
- internal const int ERROR_INVALID_SECURITY_DESCR = 0x53A;
- internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
- internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543;
- internal const int ERROR_NO_SECURITY_ON_OBJECT = 0x546;
- internal const int ERROR_NO_SYSTEM_RESOURCES = 0x5AA;
- internal const int ERROR_TRUSTED_RELATIONSHIP_FAILURE = 0x6FD;
-
- // Error codes from ntstatus.h
- internal const uint STATUS_SUCCESS = 0x00000000;
- internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107;
- internal const uint STATUS_NO_MEMORY = 0xC0000017;
- internal const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034;
- internal const uint STATUS_NONE_MAPPED = 0xC0000073;
- internal const uint STATUS_INSUFFICIENT_RESOURCES = 0xC000009A;
- internal const uint STATUS_ACCESS_DENIED = 0xC0000022;
-
- internal const int INVALID_FILE_SIZE = -1;
-
- // From WinStatus.h
- internal const int STATUS_ACCOUNT_RESTRICTION = unchecked((int)0xC000006E);
-
- // Win32 Structs in N/Direct style
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- [BestFitMapping(false)]
- internal class WIN32_FIND_DATA
- {
- internal int dwFileAttributes = 0;
- // ftCreationTime was a by-value FILETIME structure
- internal uint ftCreationTime_dwLowDateTime = 0;
- internal uint ftCreationTime_dwHighDateTime = 0;
- // ftLastAccessTime was a by-value FILETIME structure
- internal uint ftLastAccessTime_dwLowDateTime = 0;
- internal uint ftLastAccessTime_dwHighDateTime = 0;
- // ftLastWriteTime was a by-value FILETIME structure
- internal uint ftLastWriteTime_dwLowDateTime = 0;
- internal uint ftLastWriteTime_dwHighDateTime = 0;
- internal int nFileSizeHigh = 0;
- internal int nFileSizeLow = 0;
- // If the file attributes' reparse point flag is set, then
- // dwReserved0 is the file tag (aka reparse tag) for the
- // reparse point. Use this to figure out whether something is
- // a volume mount point or a symbolic link.
- internal int dwReserved0 = 0;
- internal int dwReserved1 = 0;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
- internal String cFileName = null;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
- internal String cAlternateFileName = null;
- }
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
- internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] Win32Native.WIN32_FIND_DATA data);
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
- internal static extern bool FindNextFile(
- SafeFindHandle hndFindFile,
- [In, Out, MarshalAs(UnmanagedType.LPStruct)]
- WIN32_FIND_DATA lpFindFileData);
-
- [DllImport(Interop.Libraries.Kernel32)]
- internal static extern bool FindClose(IntPtr handle);
-
- [DllImport(Interop.Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
- internal static extern bool GetFileAttributesEx(String name, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
-
[DllImport(Interop.Libraries.Kernel32)]
internal static extern unsafe int WideCharToMultiByte(uint cp, uint flags, char* pwzSource, int cchSource, byte* pbDestBuffer, int cbDestBuffer, IntPtr null1, IntPtr null2);
diff --git a/src/mscorlib/src/System/Environment.cs b/src/mscorlib/src/System/Environment.cs
index 55ba52ce54..78ec2a0164 100644
--- a/src/mscorlib/src/System/Environment.cs
+++ b/src/mscorlib/src/System/Environment.cs
@@ -498,7 +498,7 @@ namespace System
{
int requiredSize = Win32Native.GetEnvironmentVariable(variable, buffer);
- if (requiredSize == 0 && Marshal.GetLastWin32Error() == Win32Native.ERROR_ENVVAR_NOT_FOUND)
+ if (requiredSize == 0 && Marshal.GetLastWin32Error() == Interop.Errors.ERROR_ENVVAR_NOT_FOUND)
{
return null;
}
@@ -664,15 +664,15 @@ namespace System
switch (errorCode)
{
- case Win32Native.ERROR_ENVVAR_NOT_FOUND:
+ case Interop.Errors.ERROR_ENVVAR_NOT_FOUND:
// Allow user to try to clear a environment variable
return;
- case Win32Native.ERROR_FILENAME_EXCED_RANGE:
+ case Interop.Errors.ERROR_FILENAME_EXCED_RANGE:
// The error message from Win32 is "The filename or extension is too long",
// which is not accurate.
throw new ArgumentException(SR.Format(SR.Argument_LongEnvVarValue));
- case Win32Native.ERROR_NOT_ENOUGH_MEMORY:
- case Win32Native.ERROR_NO_SYSTEM_RESOURCES:
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ case Interop.Errors.ERROR_NO_SYSTEM_RESOURCES:
throw new OutOfMemoryException(Interop.Kernel32.GetMessage(errorCode));
default:
throw new ArgumentException(Interop.Kernel32.GetMessage(errorCode));
diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs
deleted file mode 100644
index bb05022878..0000000000
--- a/src/mscorlib/src/System/IO/Directory.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exposes routines for enumerating through a
-** directory.
-**
-** April 11,2000
-**
-===========================================================*/
-
-using System.Collections.Generic;
-using System.Security;
-using Microsoft.Win32;
-using Microsoft.Win32.SafeHandles;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
-
-namespace System.IO
-{
- internal static class Directory
- {
- // Private class that holds search data that is passed around
- // in the heap based stack recursion
- internal sealed class SearchData
- {
- public SearchData(String fullPath, String userPath, SearchOption searchOption)
- {
- Debug.Assert(fullPath != null && fullPath.Length > 0);
- Debug.Assert(userPath != null && userPath.Length > 0);
- Debug.Assert(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- this.fullPath = fullPath;
- this.userPath = userPath;
- this.searchOption = searchOption;
- }
-
- public readonly string fullPath; // Fully qualified search path excluding the search criteria in the end (ex, c:\temp\bar\foo)
- public readonly string userPath; // User specified path (ex, bar\foo)
- public readonly SearchOption searchOption;
- }
-
-#if PLATFORM_UNIX
- public static IEnumerable<String> EnumerateFiles(String path, String searchPattern, SearchOption searchOption)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
- if (searchPattern == null)
- throw new ArgumentNullException(nameof(searchPattern));
- if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), SR.ArgumentOutOfRange_Enum);
-
- return InternalEnumerateFiles(path, searchPattern, searchOption);
- }
-
- private static IEnumerable<String> InternalEnumerateFiles(String path, String searchPattern, SearchOption searchOption)
- {
- Debug.Assert(path != null);
- Debug.Assert(searchPattern != null);
- Debug.Assert(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return EnumerateFileSystemNames(path, searchPattern, searchOption, true, false);
- }
-
- private static IEnumerable<String> EnumerateFileSystemNames(String path, String searchPattern, SearchOption searchOption,
- bool includeFiles, bool includeDirs)
- {
- Debug.Assert(path != null);
- Debug.Assert(searchPattern != null);
- Debug.Assert(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
-
- return FileSystemEnumerableFactory.CreateFileNameIterator(path, path, searchPattern,
- includeFiles, includeDirs, searchOption, true);
- }
-#endif // PLATFORM_UNIX
- }
-}
-
diff --git a/src/mscorlib/src/System/IO/File.cs b/src/mscorlib/src/System/IO/File.cs
deleted file mode 100644
index 6640c6506f..0000000000
--- a/src/mscorlib/src/System/IO/File.cs
+++ /dev/null
@@ -1,234 +0,0 @@
-// 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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: A collection of methods for manipulating Files.
-**
-** April 09,2000 (some design refactorization)
-**
-===========================================================*/
-
-using Win32Native = Microsoft.Win32.Win32Native;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-using Microsoft.Win32.SafeHandles;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace System.IO
-{
- // Class for creating FileStream objects, and some basic file management
- // routines such as Delete, etc.
- internal static class File
- {
- private const int ERROR_INVALID_PARAMETER = 87;
- internal const int GENERIC_READ = unchecked((int)0x80000000);
-
- private const int GetFileExInfoStandard = 0;
-
- // 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)
- {
- return InternalExistsHelper(path);
- }
-
- private static bool InternalExistsHelper(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;
- }
-
- internal static bool InternalExists(String path)
- {
- Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
- int dataInitialised = FillAttributeInfo(path, ref data, false, true);
-
- return (dataInitialised == 0) && (data.fileAttributes != -1)
- && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0);
- }
-
- public static byte[] ReadAllBytes(String path)
- {
- byte[] bytes;
- using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,
- FileStream.DefaultBufferSize, FileOptions.None))
- {
- // Do a blocking read
- int index = 0;
- long fileLength = fs.Length;
- if (fileLength > Int32.MaxValue)
- throw new IOException(SR.IO_FileTooLong2GB);
- int count = (int)fileLength;
- bytes = new byte[count];
- while (count > 0)
- {
- int n = fs.Read(bytes, index, count);
- if (n == 0)
- throw Error.GetEndOfFile();
- index += n;
- count -= n;
- }
- }
- return bytes;
- }
-
- // 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.Fail("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;
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs
deleted file mode 100644
index 9e52d255cc..0000000000
--- a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs
+++ /dev/null
@@ -1,628 +0,0 @@
-// 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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Enumerates files and dirs
-**
-===========================================================*/
-
-using System.Collections;
-using System.Collections.Generic;
-using Microsoft.Win32;
-using Microsoft.Win32.SafeHandles;
-using System.Runtime.InteropServices;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Diagnostics;
-using System.Threading;
-
-namespace System.IO
-{
- // Overview:
- // The key methods instantiate FileSystemEnumerableIterators. These compose the iterator with search result
- // handlers that instantiate the FileInfo, DirectoryInfo, String, etc. The handlers then perform any
- // additional required permission demands.
- internal static class FileSystemEnumerableFactory
- {
- internal static IEnumerable<String> CreateFileNameIterator(String path, String originalUserPath, String searchPattern,
- bool includeFiles, bool includeDirs, SearchOption searchOption, bool checkHost)
- {
- Debug.Assert(path != null);
- Debug.Assert(originalUserPath != null);
- Debug.Assert(searchPattern != null);
-
- SearchResultHandler<String> handler = new StringResultHandler(includeFiles, includeDirs);
- return new FileSystemEnumerableIterator<String>(path, originalUserPath, searchPattern, searchOption, handler, checkHost);
- }
- }
-
- // Abstract Iterator, borrowed from Linq. Used in anticipation of need for similar enumerables
- // in the future
- abstract internal class Iterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
- {
- int threadId;
- internal int state;
- internal TSource current;
-
- public Iterator()
- {
- threadId = Thread.CurrentThread.ManagedThreadId;
- }
-
- public TSource Current
- {
- get { return current; }
- }
-
- protected abstract Iterator<TSource> Clone();
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- current = default(TSource);
- state = -1;
- }
-
- public IEnumerator<TSource> GetEnumerator()
- {
- if (threadId == Thread.CurrentThread.ManagedThreadId && state == 0)
- {
- state = 1;
- return this;
- }
-
- Iterator<TSource> duplicate = Clone();
- duplicate.state = 1;
- return duplicate;
- }
-
- public abstract bool MoveNext();
-
- object IEnumerator.Current
- {
- get { return Current; }
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- void IEnumerator.Reset()
- {
- throw new NotSupportedException();
- }
-
- }
-
- // Overview:
- // Enumerates file system entries matching the search parameters. For recursive searches this
- // searches through all the sub dirs and executes the search criteria against every dir.
- //
- // Generic implementation:
- // FileSystemEnumerableIterator is generic. When it gets a WIN32_FIND_DATA, it calls the
- // result handler to create an instance of the generic type.
- //
- // Usage:
- // Use FileSystemEnumerableFactory to obtain FSEnumerables that can enumerate file system
- // entries as String path names, FileInfos, DirectoryInfos, or FileSystemInfos.
- //
- // Security:
- // For all the dirs/files returned, demands path discovery permission for their parent folders
- internal class FileSystemEnumerableIterator<TSource> : Iterator<TSource>
- {
- private const int STATE_INIT = 1;
- private const int STATE_SEARCH_NEXT_DIR = 2;
- private const int STATE_FIND_NEXT_FILE = 3;
- private const int STATE_FINISH = 4;
-
- private SearchResultHandler<TSource> _resultHandler;
- private List<Directory.SearchData> searchStack;
- private Directory.SearchData searchData;
- private String searchCriteria;
- SafeFindHandle _hnd = null;
-
- // empty means we know in advance that we won't find any search results, which can happen if:
- // 1. we don't have a search pattern
- // 2. we're enumerating only the top directory and found no matches during the first call
- // This flag allows us to return early for these cases. We can't know this in advance for
- // SearchOption.AllDirectories because we do a "*" search for subdirs and then use the
- // searchPattern at each directory level.
- bool empty;
-
- private String userPath;
- private SearchOption searchOption;
- private String fullPath;
- private String normalizedSearchPath;
-#if !PLATFORM_UNIX
- private int _oldMode;
- private bool _setBackOldMode;
-#endif
- internal FileSystemEnumerableIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler<TSource> resultHandler, bool checkHost)
- {
- Debug.Assert(path != null);
- Debug.Assert(originalUserPath != null);
- Debug.Assert(searchPattern != null);
- Debug.Assert(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly);
- Debug.Assert(resultHandler != null);
-
-#if !PLATFORM_UNIX
- _setBackOldMode = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out _oldMode);
-#endif
-
- searchStack = new List<Directory.SearchData>();
-
- String normalizedSearchPattern = NormalizeSearchPattern(searchPattern);
-
- if (normalizedSearchPattern.Length == 0)
- {
- empty = true;
- }
- else
- {
- _resultHandler = resultHandler;
- this.searchOption = searchOption;
-
- fullPath = Path.GetFullPath(path);
- String fullSearchString = GetFullSearchString(fullPath, normalizedSearchPattern);
- normalizedSearchPath = Path.GetDirectoryName(fullSearchString);
-
- // normalize search criteria
- searchCriteria = GetNormalizedSearchCriteria(fullSearchString, normalizedSearchPath);
-
- // fix up user path
- String searchPatternDirName = Path.GetDirectoryName(normalizedSearchPattern);
- String userPathTemp = originalUserPath;
- if (searchPatternDirName != null && searchPatternDirName.Length != 0)
- {
- userPathTemp = Path.Combine(userPathTemp, searchPatternDirName);
- }
- this.userPath = userPathTemp;
-
- searchData = new Directory.SearchData(normalizedSearchPath, this.userPath, searchOption);
-
- CommonInit();
- }
-
- }
-
- private void CommonInit()
- {
- Debug.Assert(searchCriteria != null && searchData != null, "searchCriteria and searchData should be initialized");
-
- // Execute searchCriteria against the current directory
- String searchPath = Path.Combine(searchData.fullPath, searchCriteria);
-
- Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
-
- // Open a Find handle
- _hnd = Win32Native.FindFirstFile(searchPath, data);
-
- if (_hnd.IsInvalid)
- {
- int hr = Marshal.GetLastWin32Error();
- if (hr != Win32Native.ERROR_FILE_NOT_FOUND && hr != Win32Native.ERROR_NO_MORE_FILES)
- {
- HandleError(hr, searchData.fullPath);
- }
- else
- {
- // flag this as empty only if we're searching just top directory
- // Used in fast path for top directory only
- empty = searchData.searchOption == SearchOption.TopDirectoryOnly;
- }
- }
- // fast path for TopDirectoryOnly. If we have a result, go ahead and set it to
- // current. If empty, dispose handle.
- if (searchData.searchOption == SearchOption.TopDirectoryOnly)
- {
- if (empty)
- {
- _hnd.Dispose();
- }
- else
- {
- SearchResult searchResult = CreateSearchResult(searchData, data);
- if (_resultHandler.IsResultIncluded(searchResult))
- {
- current = _resultHandler.CreateObject(searchResult);
- }
- }
- }
- // for AllDirectories, we first recurse into dirs, so cleanup and add searchData
- // to the stack
- else
- {
- _hnd.Dispose();
- searchStack.Add(searchData);
- }
- }
-
- private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler<TSource> resultHandler)
- {
- this.fullPath = fullPath;
- this.normalizedSearchPath = normalizedSearchPath;
- this.searchCriteria = searchCriteria;
- this._resultHandler = resultHandler;
- this.userPath = userPath;
- this.searchOption = searchOption;
-
- searchStack = new List<Directory.SearchData>();
-
- if (searchCriteria != null)
- {
- searchData = new Directory.SearchData(normalizedSearchPath, userPath, searchOption);
- CommonInit();
- }
- else
- {
- empty = true;
- }
- }
-
- protected override Iterator<TSource> Clone()
- {
- return new FileSystemEnumerableIterator<TSource>(fullPath, normalizedSearchPath, searchCriteria, userPath, searchOption, _resultHandler);
- }
-
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (_hnd != null)
- {
- _hnd.Dispose();
- }
- }
- finally
- {
-#if !PLATFORM_UNIX
- if (_setBackOldMode)
- {
- uint _ignore;
- Interop.Kernel32.SetThreadErrorMode(_oldMode, out _ignore);
- }
-#endif
-
- base.Dispose(disposing);
- }
- }
-
- public override bool MoveNext()
- {
- Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
- switch (state)
- {
- case STATE_INIT:
- {
- if (empty)
- {
- state = STATE_FINISH;
- goto case STATE_FINISH;
- }
- if (searchData.searchOption == SearchOption.TopDirectoryOnly)
- {
- state = STATE_FIND_NEXT_FILE;
- if (current != null)
- {
- return true;
- }
- else
- {
- goto case STATE_FIND_NEXT_FILE;
- }
- }
- else
- {
- state = STATE_SEARCH_NEXT_DIR;
- goto case STATE_SEARCH_NEXT_DIR;
- }
- }
- case STATE_SEARCH_NEXT_DIR:
- {
- Debug.Assert(searchData.searchOption != SearchOption.TopDirectoryOnly, "should not reach this code path if searchOption == TopDirectoryOnly");
- // Traverse directory structure. We need to get '*'
- while (searchStack.Count > 0)
- {
- searchData = searchStack[0];
- Debug.Assert((searchData.fullPath != null), "fullpath can't be null!");
- searchStack.RemoveAt(0);
-
- // Traverse the subdirs
- AddSearchableDirsToStack(searchData);
-
- // Execute searchCriteria against the current directory
- String searchPath = Path.Combine(searchData.fullPath, searchCriteria);
-
- // Open a Find handle
- _hnd = Win32Native.FindFirstFile(searchPath, data);
- if (_hnd.IsInvalid)
- {
- int hr = Marshal.GetLastWin32Error();
- if (hr == Win32Native.ERROR_FILE_NOT_FOUND || hr == Win32Native.ERROR_NO_MORE_FILES || hr == Win32Native.ERROR_PATH_NOT_FOUND)
- continue;
-
- _hnd.Dispose();
- HandleError(hr, searchData.fullPath);
- }
-
- state = STATE_FIND_NEXT_FILE;
- SearchResult searchResult = CreateSearchResult(searchData, data);
- if (_resultHandler.IsResultIncluded(searchResult))
- {
- current = _resultHandler.CreateObject(searchResult);
- return true;
- }
- else
- {
- goto case STATE_FIND_NEXT_FILE;
- }
- }
- state = STATE_FINISH;
- goto case STATE_FINISH;
- }
- case STATE_FIND_NEXT_FILE:
- {
- if (searchData != null && _hnd != null)
- {
- // Keep asking for more matching files/dirs, add it to the list
- while (Win32Native.FindNextFile(_hnd, data))
- {
- SearchResult searchResult = CreateSearchResult(searchData, data);
- if (_resultHandler.IsResultIncluded(searchResult))
- {
- current = _resultHandler.CreateObject(searchResult);
- return true;
- }
- }
-
- // Make sure we quit with a sensible error.
- int hr = Marshal.GetLastWin32Error();
-
- if (_hnd != null)
- _hnd.Dispose();
-
- // ERROR_FILE_NOT_FOUND is valid here because if the top level
- // dir doen't contain any subdirs and matching files then
- // we will get here with this errorcode from the searchStack walk
- if ((hr != 0) && (hr != Win32Native.ERROR_NO_MORE_FILES)
- && (hr != Win32Native.ERROR_FILE_NOT_FOUND))
- {
- HandleError(hr, searchData.fullPath);
- }
- }
- if (searchData.searchOption == SearchOption.TopDirectoryOnly)
- {
- state = STATE_FINISH;
- goto case STATE_FINISH;
- }
- else
- {
- state = STATE_SEARCH_NEXT_DIR;
- goto case STATE_SEARCH_NEXT_DIR;
- }
- }
- case STATE_FINISH:
- {
- Dispose();
- break;
- }
- }
- return false;
- }
-
- private SearchResult CreateSearchResult(Directory.SearchData localSearchData, Win32Native.WIN32_FIND_DATA findData)
- {
- String userPathFinal = Path.Combine(localSearchData.userPath, findData.cFileName);
- String fullPathFinal = Path.Combine(localSearchData.fullPath, findData.cFileName);
- return new SearchResult(fullPathFinal, userPathFinal, findData);
- }
-
- private void HandleError(int hr, String path)
- {
- Dispose();
- throw Win32Marshal.GetExceptionForWin32Error(hr, path);
- }
-
- private void AddSearchableDirsToStack(Directory.SearchData localSearchData)
- {
- Debug.Assert(localSearchData != null);
-
- String searchPath = Path.Combine(localSearchData.fullPath, "*");
- SafeFindHandle hnd = null;
- Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
- try
- {
- // Get all files and dirs
- hnd = Win32Native.FindFirstFile(searchPath, data);
-
- if (hnd.IsInvalid)
- {
- int hr = Marshal.GetLastWin32Error();
-
- // This could happen if the dir doesn't contain any files.
- // Continue with the recursive search though, eventually
- // searchStack will become empty
- if (hr == Win32Native.ERROR_FILE_NOT_FOUND || hr == Win32Native.ERROR_NO_MORE_FILES || hr == Win32Native.ERROR_PATH_NOT_FOUND)
- return;
-
- HandleError(hr, localSearchData.fullPath);
- }
-
- // Add subdirs to searchStack. Exempt ReparsePoints as appropriate
- int incr = 0;
- do
- {
- if (FileSystemEnumerableHelpers.IsDir(data))
- {
- String tempFullPath = Path.Combine(localSearchData.fullPath, data.cFileName);
- String tempUserPath = Path.Combine(localSearchData.userPath, data.cFileName);
-
- SearchOption option = localSearchData.searchOption;
-
-#if EXCLUDE_REPARSEPOINTS
- // Traverse reparse points depending on the searchoption specified
- if ((searchDataSubDir.searchOption == SearchOption.AllDirectories) && (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_REPARSE_POINT)))
- option = SearchOption.TopDirectoryOnly;
-#endif
- // Setup search data for the sub directory and push it into the stack
- Directory.SearchData searchDataSubDir = new Directory.SearchData(tempFullPath, tempUserPath, option);
-
- searchStack.Insert(incr++, searchDataSubDir);
- }
- } while (Win32Native.FindNextFile(hnd, data));
- // We don't care about errors here
- }
- finally
- {
- if (hnd != null)
- hnd.Dispose();
- }
- }
-
- private static String NormalizeSearchPattern(String searchPattern)
- {
- Debug.Assert(searchPattern != null);
-
- // Make this corner case more useful, like dir
- if (searchPattern.Equals("."))
- {
- return "*";
- }
-
- PathInternal.CheckSearchPattern(searchPattern);
- return searchPattern;
- }
-
- private static String GetNormalizedSearchCriteria(String fullSearchString, String fullPathMod)
- {
- Debug.Assert(fullSearchString != null);
- Debug.Assert(fullPathMod != null);
- Debug.Assert(fullSearchString.Length >= fullPathMod.Length);
-
- String searchCriteria = null;
- char lastChar = fullPathMod[fullPathMod.Length - 1];
- if (PathInternal.IsDirectorySeparator(lastChar))
- {
- // Can happen if the path is C:\temp, in which case GetDirectoryName would return C:\
- searchCriteria = fullSearchString.Substring(fullPathMod.Length);
- }
- else
- {
- Debug.Assert(fullSearchString.Length > fullPathMod.Length);
- searchCriteria = fullSearchString.Substring(fullPathMod.Length + 1);
- }
- return searchCriteria;
- }
-
- private static String GetFullSearchString(String fullPath, String searchPattern)
- {
- Debug.Assert(fullPath != null);
- Debug.Assert(searchPattern != null);
-
- String tempStr = Path.Combine(fullPath, searchPattern);
-
- // If path ends in a trailing slash (\), append a * or we'll get a "Cannot find the file specified" exception
- char lastChar = tempStr[tempStr.Length - 1];
- if (PathInternal.IsDirectorySeparator(lastChar) || lastChar == Path.VolumeSeparatorChar)
- {
- tempStr = tempStr + '*';
- }
-
- return tempStr;
- }
- }
-
- internal abstract class SearchResultHandler<TSource>
- {
- internal abstract bool IsResultIncluded(SearchResult result);
-
- internal abstract TSource CreateObject(SearchResult result);
-
- }
-
- internal class StringResultHandler : SearchResultHandler<String>
- {
- private bool _includeFiles;
- private bool _includeDirs;
-
- internal StringResultHandler(bool includeFiles, bool includeDirs)
- {
- _includeFiles = includeFiles;
- _includeDirs = includeDirs;
- }
-
- internal override bool IsResultIncluded(SearchResult result)
- {
- bool includeFile = _includeFiles && FileSystemEnumerableHelpers.IsFile(result.FindData);
- bool includeDir = _includeDirs && FileSystemEnumerableHelpers.IsDir(result.FindData);
- Debug.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
- return (includeFile || includeDir);
- }
-
- internal override String CreateObject(SearchResult result)
- {
- return result.UserPath;
- }
- }
-
- internal sealed class SearchResult
- {
- private String fullPath; // fully-qualifed path
- private String userPath; // user-specified path
- private Win32Native.WIN32_FIND_DATA findData;
-
- internal SearchResult(String fullPath, String userPath, Win32Native.WIN32_FIND_DATA findData)
- {
- Debug.Assert(fullPath != null);
- Debug.Assert(userPath != null);
-
- this.fullPath = fullPath;
- this.userPath = userPath;
- this.findData = findData;
- }
-
- internal String FullPath
- {
- get { return fullPath; }
- }
-
- internal String UserPath
- {
- get { return userPath; }
- }
-
- internal Win32Native.WIN32_FIND_DATA FindData
- {
- get { return findData; }
- }
- }
-
- internal static class FileSystemEnumerableHelpers
- {
- internal static bool IsDir(Win32Native.WIN32_FIND_DATA data)
- {
- // Don't add "." nor ".."
- return (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))
- && !data.cFileName.Equals(".") && !data.cFileName.Equals("..");
- }
-
- internal static bool IsFile(Win32Native.WIN32_FIND_DATA data)
- {
- return 0 == (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY);
- }
-
- }
-}
-
diff --git a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
index cb091f1c14..1546c5e5cc 100644
--- a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
@@ -4,9 +4,6 @@
/*============================================================
**
-**
-**
-**
**
** Purpose: Searches for resources on disk, used for file-
** based resource lookup.
@@ -14,19 +11,16 @@
**
===========================================================*/
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Threading;
+
+using Internal.IO;
+
namespace System.Resources
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Text;
- using System.Threading;
- using System.Diagnostics;
-
internal class FileBasedResourceGroveler : IResourceGroveler
{
private ResourceManager.ResourceManagerMediator _mediator;
diff --git a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
index 6f3d064dc1..1dc986bfd4 100644
--- a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
@@ -414,7 +414,7 @@ namespace System.Resources
// denied back from the OS. This showed up for
// href-run exe's at one point.
int hr = fle._HResult;
- if (hr != Win32Marshal.MakeHRFromErrorCode(Win32Native.ERROR_ACCESS_DENIED))
+ if (hr != Win32Marshal.MakeHRFromErrorCode(Interop.Errors.ERROR_ACCESS_DENIED))
{
Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle);
}
diff --git a/src/mscorlib/src/System/Threading/EventWaitHandle.cs b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
index 38326de0c1..d3db86e4e9 100644
--- a/src/mscorlib/src/System/Threading/EventWaitHandle.cs
+++ b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
@@ -78,7 +78,7 @@ namespace System.Threading
int errorCode = Marshal.GetLastWin32Error();
_handle.SetHandleAsInvalid();
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
throw Win32Marshal.GetExceptionForWin32Error(errorCode, name);
@@ -126,12 +126,12 @@ namespace System.Threading
if (_handle.IsInvalid)
{
_handle.SetHandleAsInvalid();
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
throw Win32Marshal.GetExceptionForWin32Error(errorCode, name);
}
- createdNew = errorCode != Win32Native.ERROR_ALREADY_EXISTS;
+ createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS;
SetHandleInternal(_handle);
}
@@ -157,7 +157,7 @@ namespace System.Threading
throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
- throw Win32Marshal.GetExceptionForWin32Error(Win32Native.ERROR_PATH_NOT_FOUND, "");
+ throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, "");
default:
return result;
@@ -198,11 +198,11 @@ namespace System.Threading
{
int errorCode = Marshal.GetLastWin32Error();
- if (Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
+ if (Interop.Errors.ERROR_FILE_NOT_FOUND == errorCode || Interop.Errors.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
- if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
+ if (Interop.Errors.ERROR_PATH_NOT_FOUND == errorCode)
return OpenExistingResult.PathNotFound;
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
return OpenExistingResult.NameInvalid;
//this is for passed through Win32Native Errors
throw Win32Marshal.GetExceptionForWin32Error(errorCode, "");
diff --git a/src/mscorlib/src/System/Threading/Mutex.cs b/src/mscorlib/src/System/Threading/Mutex.cs
index 6b2b930d90..27311bfa84 100644
--- a/src/mscorlib/src/System/Threading/Mutex.cs
+++ b/src/mscorlib/src/System/Threading/Mutex.cs
@@ -66,7 +66,7 @@ namespace System.Threading
throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
- throw Win32Marshal.GetExceptionForWin32Error(Win32Native.ERROR_PATH_NOT_FOUND, name);
+ throw Win32Marshal.GetExceptionForWin32Error(Interop.Errors.ERROR_PATH_NOT_FOUND, name);
default:
return result;
@@ -153,17 +153,17 @@ namespace System.Threading
int errorCode = Marshal.GetLastWin32Error();
#if PLATFORM_UNIX
- if (name != null && errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE)
+ if (name != null && errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE)
{
// On Unix, length validation is done by CoreCLR's PAL after converting to utf-8
throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, name, WaitHandleNameMax), nameof(name));
}
#endif
- if (Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
+ if (Interop.Errors.ERROR_FILE_NOT_FOUND == errorCode || Interop.Errors.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
- if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
+ if (Interop.Errors.ERROR_PATH_NOT_FOUND == errorCode)
return OpenExistingResult.PathNotFound;
- if (null != name && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
return OpenExistingResult.NameInvalid;
// this is for passed through Win32Native Errors
diff --git a/src/mscorlib/src/System/Threading/Semaphore.cs b/src/mscorlib/src/System/Threading/Semaphore.cs
index 012d0e516d..6989130cbd 100644
--- a/src/mscorlib/src/System/Threading/Semaphore.cs
+++ b/src/mscorlib/src/System/Threading/Semaphore.cs
@@ -41,7 +41,7 @@ namespace System.Threading
{
int errorCode = Marshal.GetLastWin32Error();
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(
SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
@@ -72,12 +72,12 @@ namespace System.Threading
int errorCode = Marshal.GetLastWin32Error();
if (myHandle.IsInvalid)
{
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(
SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
throw Win32Marshal.GetExceptionForLastWin32Error();
}
- createdNew = errorCode != Win32Native.ERROR_ALREADY_EXISTS;
+ createdNew = errorCode != Interop.Errors.ERROR_ALREADY_EXISTS;
this.SafeWaitHandle = myHandle;
}
@@ -115,7 +115,7 @@ namespace System.Threading
case OpenExistingResult.NameInvalid:
throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
- throw new IOException(Interop.Kernel32.GetMessage(Win32Native.ERROR_PATH_NOT_FOUND));
+ throw new IOException(Interop.Kernel32.GetMessage(Interop.Errors.ERROR_PATH_NOT_FOUND));
default:
return result;
}
@@ -147,11 +147,11 @@ namespace System.Threading
int errorCode = Marshal.GetLastWin32Error();
- if (Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
+ if (Interop.Errors.ERROR_FILE_NOT_FOUND == errorCode || Interop.Errors.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
- if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
+ if (Interop.Errors.ERROR_PATH_NOT_FOUND == errorCode)
return OpenExistingResult.PathNotFound;
- if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Interop.Errors.ERROR_INVALID_HANDLE == errorCode)
return OpenExistingResult.NameInvalid;
//this is for passed through NativeMethods Errors
throw Win32Marshal.GetExceptionForLastWin32Error();