diff options
author | Jan Kotas <jkotas@microsoft.com> | 2018-01-29 15:22:01 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-29 15:22:01 -0800 |
commit | b29f6328510207970763580d6f4db864e4b198af (patch) | |
tree | 3ce16eef93b0db5bcb72617bdb15e4e185c760f6 | |
parent | b02961001f1978437f7bd5ba7c6d9a2c3da3c088 (diff) | |
download | coreclr-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
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(); |