Move TimeZoneInfo.Unix.cs to shared CoreLib partition (#16057)
authorJan Kotas <jkotas@microsoft.com>
Mon, 29 Jan 2018 23:22:01 +0000 (15:22 -0800)
committerGitHub <noreply@github.com>
Mon, 29 Jan 2018 23:22:01 +0000 (15:22 -0800)
- 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

23 files changed:
src/dlls/mscoree/mscorwks_unixexports.src
src/mscorlib/System.Private.CoreLib.csproj
src/mscorlib/shared/Internal/IO/File.Unix.cs [new file with mode: 0644]
src/mscorlib/shared/Internal/IO/File.Windows.cs [new file with mode: 0644]
src/mscorlib/shared/Internal/IO/File.cs [new file with mode: 0644]
src/mscorlib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs [new file with mode: 0644]
src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeDirectoryHandle.Unix.cs [new file with mode: 0644]
src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFindHandle.Windows.cs [moved from src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs with 69% similarity]
src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
src/mscorlib/shared/System/TimeZoneInfo.Unix.cs [moved from src/mscorlib/src/System/TimeZoneInfo.Unix.cs with 94% similarity]
src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
src/mscorlib/src/Microsoft/Win32/Win32Native.cs
src/mscorlib/src/System/Environment.cs
src/mscorlib/src/System/IO/Directory.cs [deleted file]
src/mscorlib/src/System/IO/File.cs [deleted file]
src/mscorlib/src/System/IO/FileSystemEnumerable.cs [deleted file]
src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
src/mscorlib/src/System/Threading/EventWaitHandle.cs
src/mscorlib/src/System/Threading/Mutex.cs
src/mscorlib/src/System/Threading/Semaphore.cs

index a3ca37c..0eae53f 100644 (file)
@@ -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
-
index 707dcee..a85e298 100644 (file)
   </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" />
     <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>
     <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 (file)
index 0000000..50fa0f0
--- /dev/null
@@ -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 (file)
index 0000000..0acae3b
--- /dev/null
@@ -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 (file)
index 0000000..2fcc0f3
--- /dev/null
@@ -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 (file)
index 0000000..d98c428
--- /dev/null
@@ -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);
+        }
+    }
+}
index 4cce56b..181fb10 100644 (file)
@@ -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 (file)
index 0000000..f7435ea
--- /dev/null
@@ -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; }
+        }
+    }
+}
@@ -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);
         }
     }
 }
index 89d7cfd..ec576aa 100644 (file)
@@ -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" />
     <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'" />
     <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'" />
     <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>
@@ -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)
index 350880e..5087f27 100644 (file)
@@ -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:
index 1338596..b69bc42 100644 (file)
@@ -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)]
index a6b28db..fbb1b35 100644 (file)
@@ -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);
 
index 55ba52c..78ec2a0 100644 (file)
@@ -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 (file)
index bb05022..0000000
+++ /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 (file)
index 6640c65..0000000
+++ /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 (file)
index 9e52d25..0000000
+++ /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);
-        }
-
-    }
-}
-
index cb091f1..1546c5e 100644 (file)
@@ -4,9 +4,6 @@
 
 /*============================================================
 **
-** 
-** 
-**
 **
 ** Purpose: Searches for resources on disk, used for file-
 ** based resource lookup.
 ** 
 ===========================================================*/
 
+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;
index 6f3d064..1dc986b 100644 (file)
@@ -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);
                 }
index 38326de..d3db86e 100644 (file)
@@ -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, "");
index 6b2b930..27311bf 100644 (file)
@@ -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
index 012d0e5..6989130 100644 (file)
@@ -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();