Pārlūkot izejas kodu

Add System.Private.CoreLib shared sources (#12162)

Taken from corefx commit 5956ad35864352b38c53aa8c2d1ce012c96b168d. Subsequent updates will happen via a mirroring bot.
dotnet bot 7 gadi atpakaļ
vecāks
revīzija
ccd7b52ca8
100 mainītis faili ar 4174 papildinājumiem un 0 dzēšanām
  1. 25 0
      netcore/System.Private.CoreLib/shared/Internal/IO/File.Unix.cs
  2. 77 0
      netcore/System.Private.CoreLib/shared/Internal/IO/File.Windows.cs
  3. 77 0
      netcore/System.Private.CoreLib/shared/Internal/IO/File.cs
  4. 26 0
      netcore/System.Private.CoreLib/shared/Internal/Padding.cs
  5. 382 0
      netcore/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs
  6. 485 0
      netcore/System.Private.CoreLib/shared/Internal/Win32/RegistryKey.cs
  7. 212 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs
  8. 172 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.IOErrors.cs
  9. 12 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.Libraries.cs
  10. 33 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
  11. 23 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
  12. 79 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
  13. 16 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.ICU.cs
  14. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
  15. 39 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
  16. 19 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
  17. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
  18. 28 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
  19. 48 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
  20. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs
  21. 31 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs
  22. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs
  23. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs
  24. 74 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs
  25. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs
  26. 22 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs
  27. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs
  28. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs
  29. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs
  30. 27 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs
  31. 28 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs
  32. 32 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs
  33. 36 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs
  34. 25 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.cs
  35. 102 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs
  36. 63 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs
  37. 65 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs
  38. 58 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs
  39. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs
  40. 27 0
      netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs
  41. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCloseKey.cs
  42. 31 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs
  43. 20 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs
  44. 20 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs
  45. 29 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs
  46. 28 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumValue.cs
  47. 19 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegFlushKey.cs
  48. 34 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs
  49. 33 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryInfoKey.cs
  50. 54 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs
  51. 62 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs
  52. 65 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegistryConstants.cs
  53. 29 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.GetRandomBytes.cs
  54. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
  55. 20 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.NTSTATUS.cs
  56. 22 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
  57. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.BOOL.cs
  58. 45 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs
  59. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.Libraries.cs
  60. 24 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CREATEFILE2_EXTENDED_PARAMETERS.cs
  61. 16 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CancelIoEx.cs
  62. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CloseHandle.cs
  63. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Constants.cs
  64. 40 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs
  65. 32 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs
  66. 28 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs
  67. 39 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FILE_INFO_BY_HANDLE_CLASS.cs
  68. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs
  69. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileTypes.cs
  70. 16 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs
  71. 43 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs
  72. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FlushFileBuffers.cs
  73. 88 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FormatMessage.cs
  74. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs
  75. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FreeLibrary.cs
  76. 24 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCPInfo.cs
  77. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs
  78. 94 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs
  79. 25 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.cs
  80. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileType_SafeHandle.cs
  81. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFullPathNameW.cs
  82. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs
  83. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs
  84. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs
  85. 129 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs
  86. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.LoadLibraryEx.cs
  87. 20 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.LockFile.cs
  88. 11 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MAX_PATH.cs
  89. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MUI.cs
  90. 20 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MultiByteToWideChar.cs
  91. 24 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs
  92. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs
  93. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs
  94. 22 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs
  95. 17 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ResolveLocaleName.cs
  96. 21 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs
  97. 18 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SecurityOptions.cs
  98. 22 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs
  99. 15 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SetEndOfFile.cs
  100. 14 0
      netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs

+ 25 - 0
netcore/System.Private.CoreLib/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);
+        }
+    }
+}

+ 77 - 0
netcore/System.Private.CoreLib/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;
+        }
+    }
+}

+ 77 - 0
netcore/System.Private.CoreLib/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;
+            }
+        }
+    }
+}

+ 26 - 0
netcore/System.Private.CoreLib/shared/Internal/Padding.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.Runtime.InteropServices;
+
+namespace Internal
+{
+    /// <summary>A class for common padding constants and eventually routines.</summary>
+    internal static class PaddingHelpers
+    {
+        /// <summary>A size greater than or equal to the size of the most common CPU cache lines.</summary>
+#if ARM64
+        internal const int CACHE_LINE_SIZE = 128;
+#else
+        internal const int CACHE_LINE_SIZE = 64;
+#endif
+    }
+
+    /// <summary>Padding structure used to minimize false sharing</summary>
+    [StructLayout(LayoutKind.Explicit, Size = PaddingHelpers.CACHE_LINE_SIZE - sizeof(int))]
+    internal struct PaddingFor32
+    {
+    }
+}
+

+ 382 - 0
netcore/System.Private.CoreLib/shared/Internal/Runtime/CompilerServices/Unsafe.cs

@@ -0,0 +1,382 @@
+// 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.CompilerServices;
+using System.Runtime.Versioning;
+
+#if BIT64
+using nuint = System.UInt64;
+using nint = System.Int64;
+#else
+using nuint = System.UInt32;
+using nint = System.Int32;
+#endif
+
+//
+// The implementations of most the methods in this file are provided as intrinsics.
+// In CoreCLR, the body of the functions are replaced by the EE with unsafe code. See see getILIntrinsicImplementationForUnsafe for details.
+// In CoreRT, see Internal.IL.Stubs.UnsafeIntrinsics for details.
+//
+
+namespace Internal.Runtime.CompilerServices
+{
+    //
+    // Subsetted clone of System.Runtime.CompilerServices.Unsafe for internal runtime use.
+    // Keep in sync with https://github.com/dotnet/corefx/tree/master/src/System.Runtime.CompilerServices.Unsafe.
+    //
+
+    /// <summary>
+    /// For internal use only. Contains generic, low-level functionality for manipulating pointers.
+    /// </summary>
+    [CLSCompliant(false)]
+    public static unsafe class Unsafe
+    {
+        /// <summary>
+        /// Returns a pointer to the given by-ref parameter.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void* AsPointer<T>(ref T value)
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // conv.u
+            // ret
+        }
+
+        /// <summary>
+        /// Returns the size of an object of the given type parameter.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static int SizeOf<T>()
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+#endif
+            throw new PlatformNotSupportedException();
+
+            // sizeof !!0
+            // ret
+        }
+
+        /// <summary>
+        /// Casts the given object to the specified type, performs no dynamic type checking.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T As<T>(object value) where T : class
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ret
+        }
+
+        /// <summary>
+        /// Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo"/>.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref TTo As<TFrom, TTo>(ref TFrom source)
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ret
+        }
+
+        /// <summary>
+        /// Adds an element offset to the given reference.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T Add<T>(ref T source, int elementOffset)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            return ref AddByteOffset(ref source, (IntPtr)(elementOffset * (nint)SizeOf<T>()));
+#endif
+        }
+
+        /// <summary>
+        /// Adds an element offset to the given reference.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T Add<T>(ref T source, IntPtr elementOffset)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            return ref AddByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)SizeOf<T>()));
+#endif
+        }
+
+        /// <summary>
+        /// Adds an element offset to the given pointer.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void* Add<T>(void* source, int elementOffset)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            return (byte*)source + (elementOffset * (nint)SizeOf<T>());
+#endif
+        }
+
+        /// <summary>
+        /// Adds an element offset to the given reference.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        internal static ref T AddByteOffset<T>(ref T source, nuint byteOffset)
+        {
+            return ref AddByteOffset(ref source, (IntPtr)(void*)byteOffset);
+        }
+
+        /// <summary>
+        /// Determines whether the specified references point to the same location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool AreSame<T>(ref T left, ref T right)
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ldarg.1
+            // ceq
+            // ret
+        }
+
+        /// <summary>
+        /// Determines whether the memory address referenced by <paramref name="left"/> is greater than
+        /// the memory address referenced by <paramref name="right"/>.
+        /// </summary>
+        /// <remarks>
+        /// This check is conceptually similar to "(void*)(&amp;left) &gt; (void*)(&amp;right)".
+        /// </remarks>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ldarg.1
+            // cgt.un
+            // ret
+        }
+
+        /// <summary>
+        /// Determines whether the memory address referenced by <paramref name="left"/> is less than
+        /// the memory address referenced by <paramref name="right"/>.
+        /// </summary>
+        /// <remarks>
+        /// This check is conceptually similar to "(void*)(&amp;left) &lt; (void*)(&amp;right)".
+        /// </remarks>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static bool IsAddressLessThan<T>(ref T left, ref T right)
+        {
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ldarg.1
+            // clt.un
+            // ret
+        }
+
+        /// <summary>
+        /// Initializes a block of memory at the given location with a given initial value 
+        /// without assuming architecture dependent alignment of the address.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
+        {
+            for (uint i = 0; i < byteCount; i++)
+                AddByteOffset(ref startAddress, i) = value;
+        }
+
+        /// <summary>
+        /// Reads a value of type <typeparamref name="T"/> from the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T ReadUnaligned<T>(void* source)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            return Unsafe.As<byte, T>(ref *(byte*)source);
+#endif
+        }
+
+        /// <summary>
+        /// Reads a value of type <typeparamref name="T"/> from the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T ReadUnaligned<T>(ref byte source)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            return Unsafe.As<byte, T>(ref source);
+#endif
+        }
+
+        /// <summary>
+        /// Writes a value of type <typeparamref name="T"/> to the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void WriteUnaligned<T>(void* destination, T value)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            Unsafe.As<byte, T>(ref *(byte*)destination) = value;
+#endif
+        }
+
+        /// <summary>
+        /// Writes a value of type <typeparamref name="T"/> to the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void WriteUnaligned<T>(ref byte destination, T value)
+        {
+#if CORECLR
+            typeof(T).ToString(); // Type token used by the actual method body
+            throw new PlatformNotSupportedException();
+#else
+            Unsafe.As<byte, T>(ref destination) = value;
+#endif
+        }
+
+        /// <summary>
+        /// Adds an element offset to the given reference.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
+        {
+            // This method is implemented by the toolchain
+            throw new PlatformNotSupportedException();
+
+            // ldarg.0
+            // ldarg.1
+            // add
+            // ret
+        }
+
+        /// <summary>
+        /// Reads a value of type <typeparamref name="T"/> from the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T Read<T>(void* source)
+        {
+            return Unsafe.As<byte, T>(ref *(byte*)source);
+        }
+
+        /// <summary>
+        /// Reads a value of type <typeparamref name="T"/> from the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T Read<T>(ref byte source)
+        {
+            return Unsafe.As<byte, T>(ref source);
+        }
+
+        /// <summary>
+        /// Writes a value of type <typeparamref name="T"/> to the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Write<T>(void* destination, T value)
+        {
+            Unsafe.As<byte, T>(ref *(byte*)destination) = value;
+        }
+
+        /// <summary>
+        /// Writes a value of type <typeparamref name="T"/> to the given location.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void Write<T>(ref byte destination, T value)
+        {
+            Unsafe.As<byte, T>(ref destination) = value;
+        }
+
+        /// <summary>
+        /// Reinterprets the given location as a reference to a value of type <typeparamref name="T"/>.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T AsRef<T>(void* source)
+        {
+            return ref Unsafe.As<byte, T>(ref *(byte*)source);
+        }
+
+        /// <summary>
+        /// Reinterprets the given location as a reference to a value of type <typeparamref name="T"/>.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T AsRef<T>(in T source)
+        {
+            throw new PlatformNotSupportedException();
+        }
+
+        /// <summary>
+        /// Determines the byte offset from origin to target from the given references.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static IntPtr ByteOffset<T>(ref T origin, ref T target)
+        {
+            throw new PlatformNotSupportedException();
+        }
+    }
+}

+ 485 - 0
netcore/System.Private.CoreLib/shared/Internal/Win32/RegistryKey.cs

@@ -0,0 +1,485 @@
+// 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.Buffers;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Security;
+
+using Internal.Win32.SafeHandles;
+
+//
+// A minimal version of RegistryKey that supports just what CoreLib needs. 
+//
+// Internal.Win32 namespace avoids confusion with the public standalone Microsoft.Win32.Registry implementation 
+// that lives in corefx.
+//
+namespace Internal.Win32
+{
+    internal sealed class RegistryKey : IDisposable
+    {
+        // MSDN defines the following limits for registry key names & values:
+        // Key Name: 255 characters
+        // Value name:  16,383 Unicode characters
+        // Value: either 1 MB or current available memory, depending on registry format.
+        private const int MaxKeyLength = 255;
+        private const int MaxValueLength = 16383;
+
+        private SafeRegistryHandle _hkey = null;
+
+        private RegistryKey(SafeRegistryHandle hkey)
+        {
+            _hkey = hkey;
+        }
+
+        void IDisposable.Dispose()
+        {
+            if (_hkey != null)
+            {
+                _hkey.Dispose();
+            }
+        }
+
+        public void DeleteValue(string name, bool throwOnMissingValue)
+        {
+            int errorCode = Interop.Advapi32.RegDeleteValue(_hkey, name);
+
+            //
+            // 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 == Interop.Errors.ERROR_FILE_NOT_FOUND ||
+                errorCode == Interop.Errors.ERROR_FILENAME_EXCED_RANGE)
+            {
+                if (throwOnMissingValue)
+                {
+                    throw new ArgumentException(SR.Arg_RegSubKeyValueAbsent);
+                }
+                else
+                {
+                    // Otherwise, reset and just return giving no indication to the user.
+                    // (For compatibility)
+                    errorCode = 0;
+                }
+            }
+            // We really should throw an exception here if errorCode was bad,
+            // but we can't for compatibility reasons.
+            Debug.Assert(errorCode == 0, "RegDeleteValue failed.  Here's your error code: " + errorCode);
+        }
+
+        internal static RegistryKey OpenBaseKey(IntPtr hKey)
+        {
+            return new RegistryKey(new SafeRegistryHandle(hKey, false));
+        }
+
+        public RegistryKey OpenSubKey(string name)
+        {
+            return OpenSubKey(name, false);
+        }
+
+        public RegistryKey OpenSubKey(string name, bool writable)
+        {
+            // Make sure that the name does not contain double slahes
+            Debug.Assert(name.IndexOf("\\\\") == -1);
+
+            int ret = Interop.Advapi32.RegOpenKeyEx(_hkey,
+                name,
+                0,
+                writable ? 
+                    Interop.Advapi32.RegistryOperations.KEY_READ | Interop.Advapi32.RegistryOperations.KEY_WRITE :
+                    Interop.Advapi32.RegistryOperations.KEY_READ,
+                out SafeRegistryHandle result);
+
+            if (ret == 0 && !result.IsInvalid)
+            {
+                return new RegistryKey(result);
+            }
+
+            // Return null if we didn't find the key.
+            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.
+                throw new SecurityException(SR.Security_RegistryPermission);
+            }
+
+            return null;
+        }
+
+        public string[] GetSubKeyNames()
+        {
+            var names = new List<string>();
+            char[] name = ArrayPool<char>.Shared.Rent(MaxKeyLength + 1);
+
+            try
+            {
+                int result;
+                int nameLength = name.Length;
+
+                while ((result = Interop.Advapi32.RegEnumKeyEx(
+                    _hkey,
+                    names.Count,
+                    name,
+                    ref nameLength,
+                    null,
+                    null,
+                    null,
+                    null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
+                {
+                    switch (result)
+                    {
+                        case Interop.Errors.ERROR_SUCCESS:
+                            names.Add(new string(name, 0, nameLength));
+                            nameLength = name.Length;
+                            break;
+                        default:
+                            // Throw the error
+                            Win32Error(result, null);
+                            break;
+                    }
+                }
+            }
+            finally
+            {
+                ArrayPool<char>.Shared.Return(name);
+            }
+
+            return names.ToArray();
+        }
+
+        public unsafe string[] GetValueNames()
+        {
+            var names = new List<string>();
+
+            // Names in the registry aren't usually very long, although they can go to as large
+            // as 16383 characters (MaxValueLength).
+            //
+            // Every call to RegEnumValue will allocate another buffer to get the data from
+            // NtEnumerateValueKey before copying it back out to our passed in buffer. This can
+            // add up quickly- we'll try to keep the memory pressure low and grow the buffer
+            // only if needed.
+
+            char[] name = ArrayPool<char>.Shared.Rent(100);
+
+            try
+            {
+                int result;
+                int nameLength = name.Length;
+
+                while ((result = Interop.Advapi32.RegEnumValue(
+                    _hkey,
+                    names.Count,
+                    name,
+                    ref nameLength,
+                    IntPtr.Zero,
+                    null,
+                    null,
+                    null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
+                {
+                    switch (result)
+                    {
+                        // The size is only ever reported back correctly in the case
+                        // of ERROR_SUCCESS. It will almost always be changed, however.
+                        case Interop.Errors.ERROR_SUCCESS:
+                            names.Add(new string(name, 0, nameLength));
+                            break;
+                        case Interop.Errors.ERROR_MORE_DATA:
+                            {
+                                char[] oldName = name;
+                                int oldLength = oldName.Length;
+                                name = null;
+                                ArrayPool<char>.Shared.Return(oldName);
+                                name = ArrayPool<char>.Shared.Rent(checked(oldLength * 2));
+                            }
+                            break;
+                        default:
+                            // Throw the error
+                            Win32Error(result, null);
+                            break;
+                    }
+
+                    // Always set the name length back to the buffer size
+                    nameLength = name.Length;
+                }
+            }
+            finally
+            {
+                if (name != null)
+                    ArrayPool<char>.Shared.Return(name);
+            }
+
+            return names.ToArray();
+        }
+
+        public object GetValue(string name)
+        {
+            return GetValue(name, null);
+        }
+
+        public object GetValue(string name, object defaultValue)
+        {
+            object data = defaultValue;
+            int type = 0;
+            int datasize = 0;
+
+            int ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize);
+
+            if (ret != 0)
+            {
+                // 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 != Interop.Errors.ERROR_MORE_DATA)
+                    return data;
+            }
+
+            if (datasize < 0)
+            {
+                // unexpected code path
+                Debug.Fail("[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize");
+                datasize = 0;
+            }
+
+
+            switch (type)
+            {
+                case Interop.Advapi32.RegistryValues.REG_NONE:
+                case Interop.Advapi32.RegistryValues.REG_DWORD_BIG_ENDIAN:
+                case Interop.Advapi32.RegistryValues.REG_BINARY:
+                    {
+                        byte[] blob = new byte[datasize];
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
+                        data = blob;
+                    }
+                    break;
+                case Interop.Advapi32.RegistryValues.REG_QWORD:
+                    {    // also REG_QWORD_LITTLE_ENDIAN
+                        if (datasize > 8)
+                        {
+                            // prevent an AV in the edge case that datasize is larger than sizeof(long)
+                            goto case Interop.Advapi32.RegistryValues.REG_BINARY;
+                        }
+                        long blob = 0;
+                        Debug.Assert(datasize == 8, "datasize==8");
+                        // Here, datasize must be 8 when calling this
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize);
+
+                        data = blob;
+                    }
+                    break;
+                case Interop.Advapi32.RegistryValues.REG_DWORD:
+                    {    // also REG_DWORD_LITTLE_ENDIAN
+                        if (datasize > 4)
+                        {
+                            // prevent an AV in the edge case that datasize is larger than sizeof(int)
+                            goto case Interop.Advapi32.RegistryValues.REG_QWORD;
+                        }
+                        int blob = 0;
+                        Debug.Assert(datasize == 4, "datasize==4");
+                        // Here, datasize must be four when calling this
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize);
+
+                        data = blob;
+                    }
+                    break;
+
+                case Interop.Advapi32.RegistryValues.REG_SZ:
+                    {
+                        if (datasize % 2 == 1)
+                        {
+                            // handle the case where the registry contains an odd-byte length (corrupt data?)
+                            try
+                            {
+                                datasize = checked(datasize + 1);
+                            }
+                            catch (OverflowException e)
+                            {
+                                throw new IOException(SR.Arg_RegGetOverflowBug, e);
+                            }
+                        }
+                        char[] blob = new char[datasize / 2];
+
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
+                        if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
+                        {
+                            data = new string(blob, 0, blob.Length - 1);
+                        }
+                        else
+                        {
+                            // in the very unlikely case the data is missing null termination, 
+                            // pass in the whole char[] to prevent truncating a character
+                            data = new string(blob);
+                        }
+                    }
+                    break;
+
+                case Interop.Advapi32.RegistryValues.REG_EXPAND_SZ:
+                    {
+                        if (datasize % 2 == 1)
+                        {
+                            // handle the case where the registry contains an odd-byte length (corrupt data?)
+                            try
+                            {
+                                datasize = checked(datasize + 1);
+                            }
+                            catch (OverflowException e)
+                            {
+                                throw new IOException(SR.Arg_RegGetOverflowBug, e);
+                            }
+                        }
+                        char[] blob = new char[datasize / 2];
+
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
+
+                        if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
+                        {
+                            data = new string(blob, 0, blob.Length - 1);
+                        }
+                        else
+                        {
+                            // in the very unlikely case the data is missing null termination, 
+                            // pass in the whole char[] to prevent truncating a character
+                            data = new string(blob);
+                        }
+
+                        data = Environment.ExpandEnvironmentVariables((string)data);
+                    }
+                    break;
+                case Interop.Advapi32.RegistryValues.REG_MULTI_SZ:
+                    {
+                        if (datasize % 2 == 1)
+                        {
+                            // handle the case where the registry contains an odd-byte length (corrupt data?)
+                            try
+                            {
+                                datasize = checked(datasize + 1);
+                            }
+                            catch (OverflowException e)
+                            {
+                                throw new IOException(SR.Arg_RegGetOverflowBug, e);
+                            }
+                        }
+                        char[] blob = new char[datasize / 2];
+
+                        ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
+
+                        // make sure the string is null terminated before processing the data
+                        if (blob.Length > 0 && blob[blob.Length - 1] != (char)0)
+                        {
+                            Array.Resize(ref blob, blob.Length + 1);
+                        }
+
+                        string[] strings = Array.Empty<string>();
+                        int stringsCount = 0;
+
+                        int cur = 0;
+                        int len = blob.Length;
+
+                        while (ret == 0 && cur < len)
+                        {
+                            int nextNull = cur;
+                            while (nextNull < len && blob[nextNull] != (char)0)
+                            {
+                                nextNull++;
+                            }
+
+                            string toAdd = null;
+                            if (nextNull < len)
+                            {
+                                Debug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0");
+                                if (nextNull - cur > 0)
+                                {
+                                    toAdd = new string(blob, cur, nextNull - cur);
+                                }
+                                else
+                                {
+                                    // we found an empty string.  But if we're at the end of the data,
+                                    // it's just the extra null terminator.
+                                    if (nextNull != len - 1)
+                                    {
+                                        toAdd = string.Empty;
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                toAdd = new string(blob, cur, len - cur);
+                            }
+                            cur = nextNull + 1;
+
+                            if (toAdd != null)
+                            {
+                                if (strings.Length == stringsCount)
+                                {
+                                    Array.Resize(ref strings, stringsCount > 0 ? stringsCount * 2 : 4);
+                                }
+                                strings[stringsCount++] = toAdd;
+                            }
+                        }
+
+                        Array.Resize(ref strings, stringsCount);
+                        data = strings;
+                    }
+                    break;
+                case Interop.Advapi32.RegistryValues.REG_LINK:
+                default:
+                    break;
+            }
+
+            return data;
+        }
+
+        // The actual api is SetValue(string name, object value) but we only need to set Strings
+        // so this is a cut-down version that supports on that.
+        internal void SetValue(string name, string value)
+        {
+            if (value == null)
+                throw new ArgumentNullException(nameof(value));
+
+            if (name != null && name.Length > MaxValueLength)
+                throw new ArgumentException(SR.Arg_RegValStrLenBug, nameof(name));
+
+            int ret = Interop.Advapi32.RegSetValueEx(_hkey,
+                name,
+                0,
+                Interop.Advapi32.RegistryValues.REG_SZ,
+                value,
+                checked(value.Length * 2 + 2));
+
+            if (ret != 0)
+            {
+                Win32Error(ret, null);
+            }
+        }
+
+        internal void Win32Error(int errorCode, string str)
+        {
+            switch (errorCode)
+            {
+                case Interop.Errors.ERROR_ACCESS_DENIED:
+                    if (str != null)
+                        throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_RegistryKeyGeneric_Key, str));
+                    else
+                        throw new UnauthorizedAccessException();
+
+                case Interop.Errors.ERROR_FILE_NOT_FOUND:
+                    throw new IOException(SR.Arg_RegKeyNotFound, errorCode);
+
+                default:
+                    throw new IOException(Interop.Kernel32.GetMessage(errorCode), errorCode);
+            }
+        }
+    }
+
+    internal static class Registry
+    {
+        /// <summary>Current User Key. This key should be used as the root for all user specific settings.</summary>
+        public static readonly RegistryKey CurrentUser = RegistryKey.OpenBaseKey(unchecked((IntPtr)(int)0x80000001));
+
+        /// <summary>Local Machine key. This key should be used as the root for all machine specific settings.</summary>
+        public static readonly RegistryKey LocalMachine = RegistryKey.OpenBaseKey(unchecked((IntPtr)(int)0x80000002));
+    }
+}

+ 212 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs

@@ -0,0 +1,212 @@
+// 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;
+
+internal static partial class Interop
+{
+    /// <summary>Common Unix errno error codes.</summary>
+    internal enum Error
+    {
+        // These values were defined in src/Native/System.Native/fxerrno.h
+        //
+        // They compare against values obtained via Interop.Sys.GetLastError() not Marshal.GetLastWin32Error()
+        // which obtains the raw errno that varies between unixes. The strong typing as an enum is meant to
+        // prevent confusing the two. Casting to or from int is suspect. Use GetLastErrorInfo() if you need to
+        // correlate these to the underlying platform values or obtain the corresponding error message.
+        // 
+
+        SUCCESS          = 0,
+
+        E2BIG            = 0x10001,           // Argument list too long.
+        EACCES           = 0x10002,           // Permission denied.
+        EADDRINUSE       = 0x10003,           // Address in use.
+        EADDRNOTAVAIL    = 0x10004,           // Address not available.
+        EAFNOSUPPORT     = 0x10005,           // Address family not supported.
+        EAGAIN           = 0x10006,           // Resource unavailable, try again (same value as EWOULDBLOCK),
+        EALREADY         = 0x10007,           // Connection already in progress.
+        EBADF            = 0x10008,           // Bad file descriptor.
+        EBADMSG          = 0x10009,           // Bad message.
+        EBUSY            = 0x1000A,           // Device or resource busy.
+        ECANCELED        = 0x1000B,           // Operation canceled.
+        ECHILD           = 0x1000C,           // No child processes.
+        ECONNABORTED     = 0x1000D,           // Connection aborted.
+        ECONNREFUSED     = 0x1000E,           // Connection refused.
+        ECONNRESET       = 0x1000F,           // Connection reset.
+        EDEADLK          = 0x10010,           // Resource deadlock would occur.
+        EDESTADDRREQ     = 0x10011,           // Destination address required.
+        EDOM             = 0x10012,           // Mathematics argument out of domain of function.
+        EDQUOT           = 0x10013,           // Reserved.
+        EEXIST           = 0x10014,           // File exists.
+        EFAULT           = 0x10015,           // Bad address.
+        EFBIG            = 0x10016,           // File too large.
+        EHOSTUNREACH     = 0x10017,           // Host is unreachable.
+        EIDRM            = 0x10018,           // Identifier removed.
+        EILSEQ           = 0x10019,           // Illegal byte sequence.
+        EINPROGRESS      = 0x1001A,           // Operation in progress.
+        EINTR            = 0x1001B,           // Interrupted function.
+        EINVAL           = 0x1001C,           // Invalid argument.
+        EIO              = 0x1001D,           // I/O error.
+        EISCONN          = 0x1001E,           // Socket is connected.
+        EISDIR           = 0x1001F,           // Is a directory.
+        ELOOP            = 0x10020,           // Too many levels of symbolic links.
+        EMFILE           = 0x10021,           // File descriptor value too large.
+        EMLINK           = 0x10022,           // Too many links.
+        EMSGSIZE         = 0x10023,           // Message too large.
+        EMULTIHOP        = 0x10024,           // Reserved.
+        ENAMETOOLONG     = 0x10025,           // Filename too long.
+        ENETDOWN         = 0x10026,           // Network is down.
+        ENETRESET        = 0x10027,           // Connection aborted by network.
+        ENETUNREACH      = 0x10028,           // Network unreachable.
+        ENFILE           = 0x10029,           // Too many files open in system.
+        ENOBUFS          = 0x1002A,           // No buffer space available.
+        ENODEV           = 0x1002C,           // No such device.
+        ENOENT           = 0x1002D,           // No such file or directory.
+        ENOEXEC          = 0x1002E,           // Executable file format error.
+        ENOLCK           = 0x1002F,           // No locks available.
+        ENOLINK          = 0x10030,           // Reserved.
+        ENOMEM           = 0x10031,           // Not enough space.
+        ENOMSG           = 0x10032,           // No message of the desired type.
+        ENOPROTOOPT      = 0x10033,           // Protocol not available.
+        ENOSPC           = 0x10034,           // No space left on device.
+        ENOSYS           = 0x10037,           // Function not supported.
+        ENOTCONN         = 0x10038,           // The socket is not connected.
+        ENOTDIR          = 0x10039,           // Not a directory or a symbolic link to a directory.
+        ENOTEMPTY        = 0x1003A,           // Directory not empty.
+        ENOTRECOVERABLE  = 0x1003B,           // State not recoverable.
+        ENOTSOCK         = 0x1003C,           // Not a socket.
+        ENOTSUP          = 0x1003D,           // Not supported (same value as EOPNOTSUP).
+        ENOTTY           = 0x1003E,           // Inappropriate I/O control operation.
+        ENXIO            = 0x1003F,           // No such device or address.
+        EOVERFLOW        = 0x10040,           // Value too large to be stored in data type.
+        EOWNERDEAD       = 0x10041,           // Previous owner died.
+        EPERM            = 0x10042,           // Operation not permitted.
+        EPIPE            = 0x10043,           // Broken pipe.
+        EPROTO           = 0x10044,           // Protocol error.
+        EPROTONOSUPPORT  = 0x10045,           // Protocol not supported.
+        EPROTOTYPE       = 0x10046,           // Protocol wrong type for socket.
+        ERANGE           = 0x10047,           // Result too large.
+        EROFS            = 0x10048,           // Read-only file system.
+        ESPIPE           = 0x10049,           // Invalid seek.
+        ESRCH            = 0x1004A,           // No such process.
+        ESTALE           = 0x1004B,           // Reserved.
+        ETIMEDOUT        = 0x1004D,           // Connection timed out.
+        ETXTBSY          = 0x1004E,           // Text file busy.
+        EXDEV            = 0x1004F,           // Cross-device link.
+        ESOCKTNOSUPPORT  = 0x1005E,           // Socket type not supported.
+        EPFNOSUPPORT     = 0x10060,           // Protocol family not supported.
+        ESHUTDOWN        = 0x1006C,           // Socket shutdown.
+        EHOSTDOWN        = 0x10070,           // Host is down.
+        ENODATA          = 0x10071,           // No data available.
+
+        // Custom Error codes to track errors beyond kernel interface.
+        EHOSTNOTFOUND    = 0x20001,           // Name lookup failed
+
+        // POSIX permits these to have the same value and we make them always equal so
+        // that CoreFX cannot introduce a dependency on distinguishing between them that
+        // would not work on all platforms.
+        EOPNOTSUPP      = ENOTSUP,            // Operation not supported on socket.
+        EWOULDBLOCK     = EAGAIN,             // Operation would block.
+    }
+
+
+    // Represents a platform-agnostic Error and underlying platform-specific errno
+    internal struct ErrorInfo
+    {
+        private Error _error;
+        private int _rawErrno;
+
+        internal ErrorInfo(int errno)
+        {
+            _error = Interop.Sys.ConvertErrorPlatformToPal(errno);
+            _rawErrno = errno;
+        }
+
+        internal ErrorInfo(Error error)
+        {
+            _error = error;
+            _rawErrno = -1;
+        }
+
+        internal Error Error
+        {
+            get { return _error; }
+        }
+
+        internal int RawErrno
+        {
+            get { return _rawErrno == -1 ? (_rawErrno = Interop.Sys.ConvertErrorPalToPlatform(_error)) : _rawErrno; }
+        }
+
+        internal string GetErrorMessage()
+        {
+            return Interop.Sys.StrError(RawErrno);
+        }
+
+        public override string ToString()
+        {
+            return string.Format(
+                "RawErrno: {0} Error: {1} GetErrorMessage: {2}", // No localization required; text is member names used for debugging purposes
+                RawErrno, Error, GetErrorMessage());
+        }
+    }
+
+    internal partial class Sys
+    {
+        internal static Error GetLastError()
+        {
+            return ConvertErrorPlatformToPal(Marshal.GetLastWin32Error());
+        }
+
+        internal static ErrorInfo GetLastErrorInfo()
+        {
+            return new ErrorInfo(Marshal.GetLastWin32Error());
+        }
+
+        internal static unsafe string StrError(int platformErrno)
+        {
+            int maxBufferLength = 1024; // should be long enough for most any UNIX error
+            byte* buffer = stackalloc byte[maxBufferLength];
+            byte* message = StrErrorR(platformErrno, buffer, maxBufferLength);
+
+            if (message == null)
+            {
+                // This means the buffer was not large enough, but still contains
+                // as much of the error message as possible and is guaranteed to
+                // be null-terminated. We're not currently resizing/retrying because
+                // maxBufferLength is large enough in practice, but we could do
+                // so here in the future if necessary.
+                message = buffer;
+            }
+
+            return Marshal.PtrToStringAnsi((IntPtr)message);
+        }
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPlatformToPal")]
+        internal static extern Error ConvertErrorPlatformToPal(int platformErrno);
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPalToPlatform")]
+        internal static extern int ConvertErrorPalToPlatform(Error error);
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_StrErrorR")]
+        private static extern unsafe byte* StrErrorR(int platformErrno, byte* buffer, int bufferSize);
+    }
+}
+
+// NOTE: extension method can't be nested inside Interop class.
+internal static class InteropErrorExtensions
+{
+    // Intended usage is e.g. Interop.Error.EFAIL.Info() for brevity
+    // vs. new Interop.ErrorInfo(Interop.Error.EFAIL) for synthesizing
+    // errors. Errors originated from the system should be obtained
+    // via GetLastErrorInfo(), not GetLastError().Info() as that will
+    // convert twice, which is not only inefficient but also lossy if
+    // we ever encounter a raw errno that no equivalent in the Error
+    // enum.
+    public static Interop.ErrorInfo Info(this Interop.Error error)
+    {
+        return new Interop.ErrorInfo(error);
+    }
+}

+ 172 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.IOErrors.cs

@@ -0,0 +1,172 @@
+// 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.IO;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    private static void ThrowExceptionForIoErrno(ErrorInfo errorInfo, string path, bool isDirectory, Func<ErrorInfo, ErrorInfo> errorRewriter)
+    {
+        Debug.Assert(errorInfo.Error != Error.SUCCESS);
+        Debug.Assert(errorInfo.Error != Error.EINTR, "EINTR errors should be handled by the native shim and never bubble up to managed code");
+
+        if (errorRewriter != null)
+        {
+            errorInfo = errorRewriter(errorInfo);
+        }
+
+        throw Interop.GetExceptionForIoErrno(errorInfo, path, isDirectory);
+    }
+
+    internal static void CheckIo(Error error, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+    {
+        if (error != Interop.Error.SUCCESS)
+        {
+            ThrowExceptionForIoErrno(error.Info(), path, isDirectory, errorRewriter);
+        }
+    }
+
+    /// <summary>
+    /// Validates the result of system call that returns greater than or equal to 0 on success
+    /// and less than 0 on failure, with errno set to the error code.
+    /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+    /// </summary>
+    /// <param name="result">The result of the system call.</param>
+    /// <param name="path">The path with which this error is associated.  This may be null.</param>
+    /// <param name="isDirectory">true if the <paramref name="path"/> is known to be a directory; otherwise, false.</param>
+    /// <param name="errorRewriter">Optional function to change an error code prior to processing it.</param>
+    /// <returns>
+    /// On success, returns the non-negative result long that was validated.
+    /// </returns>
+    internal static long CheckIo(long result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+    {
+        if (result < 0)
+        {
+            ThrowExceptionForIoErrno(Sys.GetLastErrorInfo(), path, isDirectory, errorRewriter);
+        }
+
+        return result;
+    }
+
+    /// <summary>
+    /// Validates the result of system call that returns greater than or equal to 0 on success
+    /// and less than 0 on failure, with errno set to the error code.
+    /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+    /// </summary>
+    /// <returns>
+    /// On success, returns the non-negative result int that was validated.
+    /// </returns>
+    internal static int CheckIo(int result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+    {
+        CheckIo((long)result, path, isDirectory, errorRewriter);
+
+        return result;
+    }
+
+    /// <summary>
+    /// Validates the result of system call that returns greater than or equal to 0 on success
+    /// and less than 0 on failure, with errno set to the error code.
+    /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+    /// </summary>
+    /// <returns>
+    /// On success, returns the non-negative result IntPtr that was validated.
+    /// </returns>
+    internal static IntPtr CheckIo(IntPtr result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+    {
+        CheckIo((long)result, path, isDirectory, errorRewriter);
+
+        return result;
+    }
+
+    /// <summary>
+    /// Validates the result of system call that returns greater than or equal to 0 on success
+    /// and less than 0 on failure, with errno set to the error code.
+    /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+    /// </summary>
+    /// <returns>
+    /// On success, returns the valid SafeFileHandle that was validated.
+    /// </returns>
+    internal static TSafeHandle CheckIo<TSafeHandle>(TSafeHandle handle, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+        where TSafeHandle : SafeHandle
+    {
+        if (handle.IsInvalid)
+        {
+            ThrowExceptionForIoErrno(Sys.GetLastErrorInfo(), path, isDirectory, errorRewriter);
+        }
+
+        return handle;
+    }
+
+    /// <summary>
+    /// Gets an Exception to represent the supplied error info.
+    /// </summary>
+    /// <param name="errorInfo">The error info</param>
+    /// <param name="path">The path with which this error is associated.  This may be null.</param>
+    /// <param name="isDirectory">true if the <paramref name="path"/> is known to be a directory; otherwise, false.</param>
+    /// <returns></returns>
+    internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string path = null, bool isDirectory = false)
+    {
+        // Translate the errno into a known set of exception types.  For cases where multiple errnos map
+        // to the same exception type, include an inner exception with the details.
+        switch (errorInfo.Error)
+        {
+            case Error.ENOENT:
+                if (isDirectory)
+                {
+                    return !string.IsNullOrEmpty(path) ?
+                        new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path)) :
+                        new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
+                }
+                else
+                {
+                    return !string.IsNullOrEmpty(path) ?
+                        new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path) :
+                        new FileNotFoundException(SR.IO_FileNotFound);
+                }
+
+            case Error.EACCES:
+            case Error.EBADF:
+            case Error.EPERM:
+                Exception inner = GetIOException(errorInfo);
+                return !string.IsNullOrEmpty(path) ?
+                    new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path), inner) :
+                    new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName, inner);
+
+            case Error.ENAMETOOLONG:
+                return !string.IsNullOrEmpty(path) ?
+                    new PathTooLongException(SR.Format(SR.IO_PathTooLong_Path, path)) :
+                    new PathTooLongException(SR.IO_PathTooLong);
+
+            case Error.EWOULDBLOCK:
+                return !string.IsNullOrEmpty(path) ?
+                    new IOException(SR.Format(SR.IO_SharingViolation_File, path), errorInfo.RawErrno) :
+                    new IOException(SR.IO_SharingViolation_NoFileName, errorInfo.RawErrno);
+
+            case Error.ECANCELED:
+                return new OperationCanceledException();
+
+            case Error.EFBIG:
+                return new ArgumentOutOfRangeException("value", SR.ArgumentOutOfRange_FileLengthTooBig);
+
+            case Error.EEXIST:
+                if (!string.IsNullOrEmpty(path))
+                {
+                    return new IOException(SR.Format(SR.IO_FileExists_Name, path), errorInfo.RawErrno);
+                }
+                goto default;
+
+            default:
+                return GetIOException(errorInfo);
+        }
+    }
+
+    internal static Exception GetIOException(Interop.ErrorInfo errorInfo)
+    {
+        return new IOException(errorInfo.GetErrorMessage(), errorInfo.RawErrno);
+    }
+}

+ 12 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/Interop.Libraries.cs

@@ -0,0 +1,12 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+    internal static partial class Libraries
+    {
+        internal const string GlobalizationNative = "System.Globalization.Native";
+        internal const string SystemNative = "System.Native";
+    }
+}

+ 33 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs

@@ -0,0 +1,33 @@
+// 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.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        internal delegate void EnumCalendarInfoCallback(
+           [MarshalAs(UnmanagedType.LPWStr)] string calendarString,
+           IntPtr context);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendars")]
+        internal static extern int GetCalendars(string localeName, CalendarId[] calendars, int calendarsCapacity);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendarInfo")]
+        internal static extern unsafe ResultCode GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType calendarDataType, char* result, int resultCapacity);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")]
+        internal static extern bool EnumCalendarInfo(EnumCalendarInfoCallback callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context);
+
+        [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLatestJapaneseEra")]
+        internal static extern int GetLatestJapaneseEra();
+
+        [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetJapaneseEraStartDate")]
+        internal static extern bool GetJapaneseEraStartDate(int era, out int startYear, out int startMonth, out int startDay);
+    }
+}

+ 23 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs

@@ -0,0 +1,23 @@
+// 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.Security;
+using System.Text;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCase")]
+        internal static extern unsafe void ChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCaseInvariant")]
+        internal static extern unsafe void ChangeCaseInvariant(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ChangeCaseTurkish")]
+        internal static extern unsafe void ChangeCaseTurkish(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
+    }
+}

+ 79 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Collation.cs

@@ -0,0 +1,79 @@
+// 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.Globalization;
+using System.Runtime.InteropServices;
+using System.Security;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortHandle")]
+        internal static extern unsafe ResultCode GetSortHandle(byte[] localeName, out SafeSortHandle sortHandle);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CloseSortHandle")]
+        internal static extern unsafe void CloseSortHandle(IntPtr handle);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareString")]
+        internal static extern unsafe int CompareString(SafeSortHandle sortHandle, char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOf")]
+        internal static extern unsafe int IndexOf(SafeSortHandle sortHandle, char* target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options, int* matchLengthPtr);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")]
+        internal static extern unsafe int LastIndexOf(SafeSortHandle sortHandle, char* target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")]
+        internal static extern unsafe int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")]
+        internal static extern unsafe int IndexOfOrdinalIgnoreCase(char* target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool StartsWith(SafeSortHandle sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool EndsWith(SafeSortHandle sortHandle, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool StartsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool EndsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortKey")]
+        internal static extern unsafe int GetSortKey(SafeSortHandle sortHandle, char* str, int strLength, byte* sortKey, int sortKeyLength, CompareOptions options);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareStringOrdinalIgnoreCase")]
+        internal static extern unsafe int CompareStringOrdinalIgnoreCase(char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len);
+
+        [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetSortVersion")]
+        internal static extern int GetSortVersion(SafeSortHandle sortHandle);
+
+        internal class SafeSortHandle : SafeHandle
+        {
+            private SafeSortHandle() :
+                base(IntPtr.Zero, true)
+            {
+            }
+
+            public override bool IsInvalid
+            {
+                get { return handle == IntPtr.Zero; }
+            }
+
+            protected override bool ReleaseHandle()
+            {
+                CloseSortHandle(handle);
+                SetHandle(IntPtr.Zero);
+                return true;
+            }
+        }
+    }
+}

+ 16 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.ICU.cs

@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_LoadICU")]
+        internal static extern int LoadICU();
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs

@@ -0,0 +1,21 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        internal const int AllowUnassigned = 0x1;
+        internal const int UseStd3AsciiRules = 0x2;
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ToAscii")]
+        internal static extern unsafe int ToAscii(uint flags, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ToUnicode")]
+        internal static extern unsafe int ToUnicode(uint flags, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+    }
+}

+ 39 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs

@@ -0,0 +1,39 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleName")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool GetLocaleName(string localeName, char* value, int valueLength);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoString")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool GetLocaleInfoString(string localeName, uint localeStringData, char* value, int valueLength);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetDefaultLocaleName")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool GetDefaultLocaleName(char* value, int valueLength);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleTimeFormat")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern unsafe bool GetLocaleTimeFormat(string localeName, bool shortFormat, char* value, int valueLength);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoInt")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern bool GetLocaleInfoInt(string localeName, uint localeNumberData, ref int value);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoGroupingSizes")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern bool GetLocaleInfoGroupingSizes(string localeName, uint localeGroupingData, ref int primaryGroupSize, ref int secondaryGroupSize);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocales")]
+        internal static extern int GetLocales([Out] char[] value, int valueLength);
+    }
+}

+ 19 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs

@@ -0,0 +1,19 @@
+// 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.Text;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IsNormalized")]
+        internal static extern int IsNormalized(NormalizationForm normalizationForm, string src, int srcLen);
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_NormalizeString")]
+        internal static extern int NormalizeString(NormalizationForm normalizationForm, string src, int srcLen, [Out] char[] dstBuffer, int dstBufferCapacity);
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs

@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        // needs to be kept in sync with ResultCode in System.Globalization.Native
+        internal enum ResultCode
+        {
+            Success = 0,
+            UnknownError = 1,
+            InsufficentBuffer = 2,
+            OutOfMemory = 3
+        }
+    }
+}

+ 28 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs

@@ -0,0 +1,28 @@
+// 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.Runtime.InteropServices;
+using System.Text;
+
+internal static partial class Interop
+{
+    internal static partial class Globalization
+    {
+        // needs to be kept in sync with TimeZoneDisplayNameType in System.Globalization.Native
+        internal enum TimeZoneDisplayNameType
+        {
+            Generic = 0,
+            Standard = 1,
+            DaylightSavings = 2,
+        }
+
+        [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetTimeZoneDisplayName")]
+        internal static extern unsafe ResultCode GetTimeZoneDisplayName(
+            string localeName, 
+            string timeZoneId, 
+            TimeZoneDisplayNameType type, 
+            char* result, 
+            int resultLength);
+    }
+}

+ 48 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs

@@ -0,0 +1,48 @@
+// 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.Buffers;
+using System.Text;
+
+internal static partial class Interop
+{
+    /// <summary>
+    /// Helper for making interop calls that return a string, but we don't know
+    /// the correct size of buffer to make. So invoke the interop call with an
+    /// increasing buffer until the size is big enough.
+    /// </summary>
+    internal static bool CallStringMethod<TArg1, TArg2, TArg3>(
+        SpanFunc<char, TArg1, TArg2, TArg3, Interop.Globalization.ResultCode> interopCall,
+        TArg1 arg1, TArg2 arg2, TArg3 arg3,
+        out string result)
+    {
+        const int InitialSize = 256; // arbitrary stack allocation size
+        const int MaxHeapSize = 1280; // max from previous version of the code, starting at 80 and doubling four times
+
+        Span<char> buffer = stackalloc char[InitialSize];
+        Interop.Globalization.ResultCode resultCode = interopCall(buffer, arg1, arg2, arg3);
+
+        if (resultCode == Interop.Globalization.ResultCode.Success)
+        {
+            result = buffer.Slice(0, buffer.IndexOf('\0')).ToString();
+            return true;
+        }
+
+        if (resultCode == Interop.Globalization.ResultCode.InsufficentBuffer)
+        {
+            // Increase the string size and try again
+            buffer = new char[MaxHeapSize];
+            if (interopCall(buffer, arg1, arg2, arg3) == Interop.Globalization.ResultCode.Success)
+            {
+                result = buffer.Slice(0, buffer.IndexOf('\0')).ToString();
+                return true;
+            }
+        }
+
+        result = null;
+        return false;
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs

@@ -0,0 +1,15 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Close", SetLastError = true)]
+        internal static extern int Close(IntPtr fd);
+    }
+}

+ 31 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs

@@ -0,0 +1,31 @@
+// 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 Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum LockOperations : int
+        {
+            LOCK_SH = 1,    /* shared lock */
+            LOCK_EX = 2,    /* exclusive lock */
+            LOCK_NB = 4,    /* don't block when locking*/
+            LOCK_UN = 8,    /* unlock */
+        }
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FLock", SetLastError = true)]
+        internal static extern int FLock(SafeFileHandle fd, LockOperations operation);
+
+        /// <summary>
+        /// Exposing this for SafeFileHandle.ReleaseHandle() to call.
+        /// Normal callers should use FLock(SafeFileHandle fd).
+        /// </summary>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FLock", SetLastError = true)]
+        internal static extern int FLock(IntPtr fd, LockOperations operation);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs

@@ -0,0 +1,15 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FSync", SetLastError = true)]
+        internal static extern int FSync(SafeFileHandle fd);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs

@@ -0,0 +1,15 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FTruncate", SetLastError = true)]
+        internal static extern int FTruncate(SafeFileHandle fd, long length);
+    }
+}

+ 74 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs

@@ -0,0 +1,74 @@
+// 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.Buffers;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetCwd", SetLastError = true)]
+        private static extern unsafe byte* GetCwd(byte* buffer, int bufferLength);
+
+        internal static unsafe string GetCwd()
+        {      
+            const int StackLimit = 256;
+       
+            // First try to get the path into a buffer on the stack
+            byte* stackBuf = stackalloc byte[StackLimit];
+            string result = GetCwdHelper(stackBuf, StackLimit);
+            if (result != null)
+            {
+                return result;
+            }
+
+            // If that was too small, try increasing large buffer sizes
+            int bufferSize = StackLimit;
+            do
+            {
+                checked { bufferSize *= 2; }
+                byte[] buf = ArrayPool<byte>.Shared.Rent(bufferSize);
+                try
+                {
+                    fixed (byte* ptr = &buf[0])
+                    {
+                        result = GetCwdHelper(ptr, buf.Length);
+                        if (result != null)
+                        {
+                            return result;
+                        }
+                    }
+                }
+                finally
+                {
+                    ArrayPool<byte>.Shared.Return(buf);
+                }
+            }
+            while (true);
+        }
+
+        private static unsafe string GetCwdHelper(byte* ptr, int bufferSize)
+        {
+            // Call the real getcwd
+            byte* result = GetCwd(ptr, bufferSize);
+
+            // If it returned non-null, the null-terminated path is in the buffer
+            if (result != null)
+            {
+                return Marshal.PtrToStringAnsi((IntPtr)ptr);
+            }
+
+            // Otherwise, if it failed due to the buffer being too small, return null;
+            // for anything else, throw.
+            ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
+            if (errorInfo.Error == Interop.Error.ERANGE)
+            {
+               return null;
+            }
+            throw Interop.GetExceptionForIoErrno(errorInfo);
+        }
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs

@@ -0,0 +1,21 @@
+// 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.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal unsafe partial class Sys
+    {
+        [DllImport(Interop.Libraries.SystemNative, EntryPoint = "SystemNative_GetNonCryptographicallySecureRandomBytes")]
+        internal static extern unsafe void GetNonCryptographicallySecureRandomBytes(byte* buffer, int length);
+    }
+
+    internal static unsafe void GetRandomBytes(byte* buffer, int length)
+    {
+        Sys.GetNonCryptographicallySecureRandomBytes(buffer, length);
+    }
+}

+ 22 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs

@@ -0,0 +1,22 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum SeekWhence
+        {
+            SEEK_SET = 0,
+            SEEK_CUR = 1,
+            SEEK_END = 2
+        }
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LSeek", SetLastError = true)]
+        internal static extern long LSeek(SafeFileHandle fd, long offset, SeekWhence whence);
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs

@@ -0,0 +1,21 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum LockType : short
+        {
+            F_WRLCK = 1,    // exclusive or write lock
+            F_UNLCK = 2     // unlock
+        }
+        
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LockFileRegion", SetLastError=true)]
+        internal static extern int LockFileRegion(SafeHandle fd, long offset, long length, LockType lockType);
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_MksTemps", SetLastError = true)]
+        internal static extern IntPtr MksTemps(
+            byte[] template, 
+            int suffixlen);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs

@@ -0,0 +1,15 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Open", SetLastError = true)]
+        internal static extern SafeFileHandle Open(string filename, OpenFlags flags, int mode);
+    }
+}

+ 27 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs

@@ -0,0 +1,27 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [Flags]
+        internal enum OpenFlags
+        {
+            // Access modes (mutually exclusive)
+            O_RDONLY = 0x0000,
+            O_WRONLY = 0x0001,
+            O_RDWR   = 0x0002,
+
+            // Flags (combinable)
+            O_CLOEXEC = 0x0010,
+            O_CREAT   = 0x0020,
+            O_EXCL    = 0x0040,
+            O_TRUNC   = 0x0080,
+            O_SYNC    = 0x0100,
+        }
+    }
+}

+ 28 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs

@@ -0,0 +1,28 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum PathConfName : int
+        {
+            PC_LINK_MAX         = 1,
+            PC_MAX_CANON        = 2,
+            PC_MAX_INPUT        = 3,
+            PC_NAME_MAX         = 4,
+            PC_PATH_MAX         = 5,
+            PC_PIPE_BUF         = 6,
+            PC_CHOWN_RESTRICTED = 7,
+            PC_NO_TRUNC         = 8,
+            PC_VDISABLE         = 9,
+        }
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_PathConf", SetLastError = true)]
+        private static extern int PathConf(string path, PathConfName name);
+    }
+}

+ 32 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs

@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [Flags]
+        internal enum Permissions
+        {
+            Mask = S_IRWXU | S_IRWXG | S_IRWXO,
+
+            S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR,
+            S_IRUSR = 0x100,
+            S_IWUSR = 0x80,
+            S_IXUSR = 0x40,
+
+            S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP,
+            S_IRGRP = 0x20,
+            S_IWGRP = 0x10,
+            S_IXGRP = 0x8,
+
+            S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH,
+            S_IROTH = 0x4,
+            S_IWOTH = 0x2,
+            S_IXOTH = 0x1,
+        }
+    }
+}

+ 36 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs

@@ -0,0 +1,36 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum FileAdvice : int
+        {
+            POSIX_FADV_NORMAL       = 0,    /* no special advice, the default value */
+            POSIX_FADV_RANDOM       = 1,    /* random I/O access */
+            POSIX_FADV_SEQUENTIAL   = 2,    /* sequential I/O access */
+            POSIX_FADV_WILLNEED     = 3,    /* will need specified pages */
+            POSIX_FADV_DONTNEED     = 4,    /* don't need the specified pages */
+            POSIX_FADV_NOREUSE      = 5,    /* data will only be accessed once */
+        }
+
+        /// <summary>
+        /// Notifies the OS kernel that the specified file will be accessed in a particular way soon; this allows the kernel to
+        /// potentially optimize the access pattern of the file.
+        /// </summary>
+        /// <param name="fd">The file descriptor of the file</param>
+        /// <param name="offset">The start of the region to advise about</param>
+        /// <param name="length">The number of bytes of the region (until the end of the file if 0)</param>
+        /// <param name="advice">The type of advice to give the kernel about the specified region</param>
+        /// <returns>
+        /// Returns 0 on success; otherwise, the error code is returned
+        /// </returns>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_PosixFAdvise", SetLastError = false /* this is explicitly called out in the man page */)]
+        internal static extern int PosixFAdvise(SafeFileHandle fd, long offset, long length, FileAdvice advice);
+    }
+}

+ 25 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.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.
+
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        /// <summary>
+        /// Reads a number of bytes from an open file descriptor into a specified buffer.
+        /// </summary>
+        /// <param name="fd">The open file descriptor to try to read from</param>
+        /// <param name="buffer">The buffer to read info into</param>
+        /// <param name="count">The size of the buffer</param>
+        /// <returns>
+        /// Returns the number of bytes read on success; otherwise, -1 is returned
+        /// Note - on fail. the position of the stream may change depending on the platform; consult man 2 read for more info
+        /// </returns>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Read", SetLastError = true)]
+        internal static extern unsafe int Read(SafeHandle fd, byte* buffer, int count);
+    }
+}

+ 102 - 0
netcore/System.Private.CoreLib/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);
+        }
+    }
+}

+ 63 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs

@@ -0,0 +1,63 @@
+// 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.Runtime.InteropServices;
+using System.Buffers;
+using System.Text;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        /// <summary>
+        /// Takes a path to a symbolic link and attempts to place the link target path into the buffer. If the buffer is too
+        /// small, the path will be truncated. No matter what, the buffer will not be null terminated. 
+        /// </summary>
+        /// <param name="path">The path to the symlink</param>
+        /// <param name="buffer">The buffer to hold the output path</param>
+        /// <param name="bufferSize">The size of the buffer</param>
+        /// <returns>
+        /// Returns the number of bytes placed into the buffer on success; bufferSize if the buffer is too small; and -1 on error.
+        /// </returns>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ReadLink", SetLastError = true)]
+        private static extern unsafe int ReadLink(string path, byte[] buffer, int bufferSize);
+
+        /// <summary>
+        /// Takes a path to a symbolic link and returns the link target path.
+        /// </summary>
+        /// <param name="path">The path to the symlink</param>
+        /// <returns>
+        /// Returns the link to the target path on success; and null otherwise.
+        /// </returns>
+        public static string ReadLink(string path)
+        {
+            int bufferSize = 256;
+            do
+            {
+                byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+                try
+                {
+                    int resultLength = Interop.Sys.ReadLink(path, buffer, buffer.Length);
+                    if (resultLength < 0)
+                    {
+                        // error
+                        return null;
+                    }
+                    else if (resultLength < buffer.Length)
+                    {
+                        // success
+                        return Encoding.UTF8.GetString(buffer, 0, resultLength);
+                    }
+                }
+                finally
+                {
+                    ArrayPool<byte>.Shared.Return(buffer);
+                }
+
+                // buffer was too small, loop around again and try with a larger buffer.
+                bufferSize *= 2;
+            } while (true);
+        }
+    }
+}

+ 65 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs

@@ -0,0 +1,65 @@
+// 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 Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        // Even though csc will by default use a sequential layout, a CS0649 warning as error
+        // is produced for un-assigned fields when no StructLayout is specified.
+        //
+        // Explicitly saying Sequential disables that warning/error for consumers which only
+        // use Stat in debug builds.
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct FileStatus
+        {
+            internal FileStatusFlags Flags;
+            internal int Mode;
+            internal uint Uid;
+            internal uint Gid;
+            internal long Size;
+            internal long ATime;
+            internal long ATimeNsec;
+            internal long MTime;
+            internal long MTimeNsec;
+            internal long CTime;
+            internal long CTimeNsec;
+            internal long BirthTime;
+            internal long BirthTimeNsec;
+            internal long Dev;
+            internal long Ino;
+        }
+
+        internal static class FileTypes
+        {
+            internal const int S_IFMT = 0xF000;
+            internal const int S_IFIFO = 0x1000;
+            internal const int S_IFCHR = 0x2000;
+            internal const int S_IFDIR = 0x4000;
+            internal const int S_IFREG = 0x8000;
+            internal const int S_IFLNK = 0xA000;
+            internal const int S_IFSOCK = 0xC000;
+        }
+
+        [Flags]
+        internal enum FileStatusFlags
+        {
+            None = 0,
+            HasBirthTime = 1,
+        }
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FStat2", SetLastError = true)]
+        internal static extern int FStat(SafeFileHandle fd, out FileStatus output);
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Stat2", SetLastError = true)]
+        internal static extern int Stat(string path, out FileStatus output);
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LStat2", SetLastError = true)]
+        internal static extern int LStat(string path, out FileStatus output);
+    }
+}

+ 58 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs

@@ -0,0 +1,58 @@
+// 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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        internal enum SysLogPriority : int
+        {
+            // Priorities
+            LOG_EMERG       = 0,        /* system is unusable */
+            LOG_ALERT       = 1,        /* action must be taken immediately */
+            LOG_CRIT        = 2,        /* critical conditions */
+            LOG_ERR         = 3,        /* error conditions */
+            LOG_WARNING     = 4,        /* warning conditions */
+            LOG_NOTICE      = 5,        /* normal but significant condition */
+            LOG_INFO        = 6,        /* informational */
+            LOG_DEBUG       = 7,        /* debug-level messages */
+            // Facilities
+            LOG_KERN        = (0<<3),   /* kernel messages */
+            LOG_USER        = (1<<3),   /* random user-level messages */
+            LOG_MAIL        = (2<<3),   /* mail system */
+            LOG_DAEMON      = (3<<3),   /* system daemons */
+            LOG_AUTH        = (4<<3),   /* authorization messages */
+            LOG_SYSLOG      = (5<<3),   /* messages generated internally by syslogd */
+            LOG_LPR         = (6<<3),   /* line printer subsystem */
+            LOG_NEWS        = (7<<3),   /* network news subsystem */
+            LOG_UUCP        = (8<<3),   /* UUCP subsystem */
+            LOG_CRON        = (9<<3),   /* clock daemon */
+            LOG_AUTHPRIV    = (10<<3),  /* authorization messages (private) */
+            LOG_FTP         = (11<<3),  /* ftp daemon */
+            // Between FTP and Local is reserved for system use
+            LOG_LOCAL0      = (16<<3),  /* reserved for local use */
+            LOG_LOCAL1      = (17<<3),  /* reserved for local use */
+            LOG_LOCAL2      = (18<<3),  /* reserved for local use */
+            LOG_LOCAL3      = (19<<3),  /* reserved for local use */
+            LOG_LOCAL4      = (20<<3),  /* reserved for local use */
+            LOG_LOCAL5      = (21<<3),  /* reserved for local use */
+            LOG_LOCAL6      = (22<<3),  /* reserved for local use */
+            LOG_LOCAL7      = (23<<3),  /* reserved for local use */
+        }
+
+        /// <summary>
+        /// Write a message to the system logger, which in turn writes the message to the system console, log files, etc. 
+        /// See man 3 syslog for more info
+        /// </summary>
+        /// <param name="priority">
+        /// The OR of a priority and facility in the SysLogPriority enum to declare the priority and facility of the log entry
+        /// </param>
+        /// <param name="message">The message to put in the log entry</param>
+        /// <param name="arg1">Like printf, the argument is passed to the variadic part of the C++ function to wildcards in the message</param>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SysLog")]
+        internal static extern void SysLog(SysLogPriority priority, string message, string arg1);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs

@@ -0,0 +1,15 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Unlink", SetLastError = true)]
+        internal static extern int Unlink(string pathname);
+    }
+}

+ 27 - 0
netcore/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs

@@ -0,0 +1,27 @@
+// 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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        /// <summary>
+        /// Writes the specified buffer to the provided open file descriptor
+        /// </summary>
+        /// <param name="fd">The file descriptor to try and write to</param>
+        /// <param name="buffer">The data to attempt to write</param>
+        /// <param name="bufferSize">The amount of data to write, in bytes</param>
+        /// <returns>
+        /// Returns the number of bytes written on success; otherwise, returns -1 and sets errno
+        /// </returns>
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Write", SetLastError = true)]
+        internal static extern unsafe int Write(SafeHandle fd, byte* buffer, int bufferSize);
+
+        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Write", SetLastError = true)]
+        internal static extern unsafe int Write(int fd, byte* buffer, int bufferSize);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCloseKey.cs

@@ -0,0 +1,15 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32)]
+        internal static extern int RegCloseKey(IntPtr hKey);
+    }
+}

+ 31 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs

@@ -0,0 +1,31 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        // Note: RegCreateKeyEx won't set the last error on failure - it returns
+        // an error code if it fails.
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW")]
+        internal static extern int RegCreateKeyEx(
+            SafeRegistryHandle hKey,
+            string lpSubKey,
+            int Reserved,
+            string lpClass,
+            int dwOptions,
+            int samDesired,
+            ref Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs,
+            out SafeRegistryHandle hkResult,
+            out int lpdwDisposition);
+    }
+}

+ 20 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs

@@ -0,0 +1,20 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW")]
+        internal static extern int RegDeleteKeyEx(SafeRegistryHandle hKey, string lpSubKey, int samDesired, int Reserved);
+    }
+}

+ 20 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs

@@ -0,0 +1,20 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW")]
+        internal static extern int RegDeleteValue(SafeRegistryHandle hKey, string lpValueName);
+    }
+}

+ 29 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs

@@ -0,0 +1,29 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW")]
+        internal static extern unsafe int RegEnumKeyEx(
+            SafeRegistryHandle hKey,
+            int dwIndex,
+            char[] lpName,
+            ref int lpcbName,
+            int[] lpReserved,
+            [Out] char[] lpClass,
+            int[] lpcbClass,
+            long[] lpftLastWriteTime);
+    }
+}

+ 28 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumValue.cs

@@ -0,0 +1,28 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW")]
+        internal static extern unsafe int RegEnumValue(
+            SafeRegistryHandle hKey,
+            int dwIndex,
+            char[] lpValueName,
+            ref int lpcbValueName,
+            IntPtr lpReserved_MustBeZero,
+            int[] lpType,
+            byte[] lpData,
+            int[] lpcbData);
+    }
+}

+ 19 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegFlushKey.cs

@@ -0,0 +1,19 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32)]
+        internal static extern int RegFlushKey(SafeRegistryHandle hKey);
+    }
+}

+ 34 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs

@@ -0,0 +1,34 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")]
+        internal static extern int RegOpenKeyEx(
+            SafeRegistryHandle hKey,
+            string lpSubKey,
+            int ulOptions,
+            int samDesired,
+            out SafeRegistryHandle hkResult);
+
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")]
+        internal static extern int RegOpenKeyEx(
+            IntPtr hKey,
+            string lpSubKey,
+            int ulOptions,
+            int samDesired,
+            out SafeRegistryHandle hkResult);
+    }
+}

+ 33 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryInfoKey.cs

@@ -0,0 +1,33 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryInfoKeyW")]
+        internal static extern int RegQueryInfoKey(
+            SafeRegistryHandle hKey,
+            [Out] char[] lpClass,
+            int[] lpcbClass,
+            IntPtr lpReserved_MustBeZero,
+            ref int lpcSubKeys,
+            int[] lpcbMaxSubKeyLen,
+            int[] lpcbMaxClassLen,
+            ref int lpcValues,
+            int[] lpcbMaxValueNameLen,
+            int[] lpcbMaxValueLen,
+            int[] lpcbSecurityDescriptor,
+            int[] lpftLastWriteTime);
+    }
+}

+ 54 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs

@@ -0,0 +1,54 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")]
+        internal static extern int RegQueryValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int[] lpReserved,
+            ref int lpType,
+            [Out] byte[] lpData,
+            ref int lpcbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")]
+        internal static extern int RegQueryValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int[] lpReserved,
+            ref int lpType,
+            ref int lpData,
+            ref int lpcbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")]
+        internal static extern int RegQueryValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int[] lpReserved,
+            ref int lpType,
+            ref long lpData,
+            ref int lpcbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")]
+        internal static extern int RegQueryValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int[] lpReserved,
+            ref int lpType,
+            [Out] char[] lpData,
+            ref int lpcbData);
+    }
+}

+ 62 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs

@@ -0,0 +1,62 @@
+// 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.
+
+#if REGISTRY_ASSEMBLY
+using Microsoft.Win32.SafeHandles;
+#else
+using Internal.Win32.SafeHandles;
+#endif
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")]
+        internal static extern int RegSetValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int Reserved,
+            int dwType,
+            byte[] lpData,
+            int cbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")]
+        internal static extern int RegSetValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int Reserved,
+            int dwType,
+            char[] lpData,
+            int cbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")]
+        internal static extern int RegSetValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int Reserved,
+            int dwType,
+            ref int lpData,
+            int cbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")]
+        internal static extern int RegSetValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int Reserved,
+            int dwType,
+            ref long lpData,
+            int cbData);
+
+        [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")]
+        internal static extern int RegSetValueEx(
+            SafeRegistryHandle hKey,
+            string lpValueName,
+            int Reserved,
+            int dwType,
+            string lpData,
+            int cbData);
+    }
+}

+ 65 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegistryConstants.cs

@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    internal partial class Advapi32
+    {
+        internal static class RegistryOptions
+        {
+            internal const int REG_OPTION_NON_VOLATILE = 0x0000;     // (default) keys are persisted beyond reboot/unload
+            internal const int REG_OPTION_VOLATILE = 0x0001;        // All keys created by the function are volatile
+            internal const int REG_OPTION_CREATE_LINK = 0x0002;     // They key is a symbolic link
+            internal const int REG_OPTION_BACKUP_RESTORE = 0x0004;  // Use SE_BACKUP_NAME process special privileges         
+        }
+
+        internal static class RegistryView
+        {
+            internal const int KEY_WOW64_64KEY = 0x0100;
+            internal const int KEY_WOW64_32KEY = 0x0200;
+        }
+
+        internal static class RegistryOperations
+        {
+            internal const int KEY_QUERY_VALUE = 0x0001;
+            internal const int KEY_SET_VALUE = 0x0002;
+            internal const int KEY_CREATE_SUB_KEY = 0x0004;
+            internal const int KEY_ENUMERATE_SUB_KEYS = 0x0008;
+            internal const int KEY_NOTIFY = 0x0010;
+            internal const int KEY_CREATE_LINK = 0x0020;
+            internal const int KEY_READ = ((STANDARD_RIGHTS_READ |
+                                                               KEY_QUERY_VALUE |
+                                                               KEY_ENUMERATE_SUB_KEYS |
+                                                               KEY_NOTIFY)
+                                                              &
+                                                              (~SYNCHRONIZE));
+
+            internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE |
+                                                               KEY_SET_VALUE |
+                                                               KEY_CREATE_SUB_KEY)
+                                                              &
+                                                              (~SYNCHRONIZE));
+
+            internal const int SYNCHRONIZE = 0x00100000;
+            internal const int READ_CONTROL = 0x00020000;
+            internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
+            internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
+        }
+
+        internal static class RegistryValues
+        {
+            internal const int REG_NONE = 0;                // No value type
+            internal const int REG_SZ = 1;                  // Unicode nul terminated string
+            internal const int REG_EXPAND_SZ = 2;           // Unicode nul terminated string
+            // (with environment variable references)
+            internal const int REG_BINARY = 3;              // Free form binary
+            internal const int REG_DWORD = 4;               // 32-bit number
+            internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD)
+            internal const int REG_DWORD_BIG_ENDIAN = 5;    // 32-bit number
+            internal const int REG_LINK = 6;                // Symbolic Link (Unicode)
+            internal const int REG_MULTI_SZ = 7;            // Multiple Unicode strings
+            internal const int REG_QWORD = 11;             // 64-bit number
+        }
+    }
+}

+ 29 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.GetRandomBytes.cs

@@ -0,0 +1,29 @@
+// 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.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal static unsafe void GetRandomBytes(byte* buffer, int length)
+    {
+        Debug.Assert(buffer != null);
+        Debug.Assert(length >= 0);
+
+        BCrypt.NTSTATUS status = BCrypt.BCryptGenRandom(IntPtr.Zero, buffer, length, BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+        if (status != BCrypt.NTSTATUS.STATUS_SUCCESS)
+        {
+            if (status == BCrypt.NTSTATUS.STATUS_NO_MEMORY)
+            {
+                throw new OutOfMemoryException();
+            }
+            else
+            {
+                throw new InvalidOperationException();
+            }
+        }
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs

@@ -0,0 +1,18 @@
+// 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.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class BCrypt
+    {
+        internal const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002;
+
+        [DllImport(Libraries.BCrypt, CharSet = CharSet.Unicode)]
+        internal static extern unsafe NTSTATUS BCryptGenRandom(IntPtr hAlgorithm, byte* pbBuffer, int cbBuffer, int dwFlags);        
+    }
+}

+ 20 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/BCrypt/Interop.NTSTATUS.cs

@@ -0,0 +1,20 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class BCrypt
+    {
+        internal enum NTSTATUS : uint
+        {
+            STATUS_SUCCESS = 0x0,
+            STATUS_NOT_FOUND = 0xc0000225,
+            STATUS_INVALID_PARAMETER = 0xc000000d,
+            STATUS_NO_MEMORY = 0xc0000017,
+            STATUS_AUTH_TAG_MISMATCH = 0xc000a002,
+        }
+    }
+}

+ 22 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs

@@ -0,0 +1,22 @@
+// 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.Security;
+
+internal partial class Interop
+{
+    internal partial class Crypt32
+    {
+        internal const uint CRYPTPROTECTMEMORY_BLOCK_SIZE = 16;
+        internal const uint CRYPTPROTECTMEMORY_SAME_PROCESS = 0;
+
+        [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
+        internal static extern bool CryptProtectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
+
+        [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
+        internal static extern bool CryptUnprotectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.BOOL.cs

@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    /// <summary>
+    /// Blittable version of Windows BOOL type. It is convenient in situations where
+    /// manual marshalling is required, or to avoid overhead of regular bool marshalling.
+    /// </summary>
+    /// <remarks>
+    /// Some Windows APIs return arbitrary integer values although the return type is defined
+    /// as BOOL. It is best to never compare BOOL to TRUE. Always use bResult != BOOL.FALSE
+    /// or bResult == BOOL.FALSE .
+    /// </remarks>
+    internal enum BOOL : int
+    {
+        FALSE = 0,
+        TRUE = 1,
+    }
+}

+ 45 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs

@@ -0,0 +1,45 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    // As defined in winerror.h and https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx
+    internal partial class Errors
+    {
+        internal const int ERROR_SUCCESS = 0x0;
+        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_DRIVE = 0xF;
+        internal const int ERROR_NO_MORE_FILES = 0x12;
+        internal const int ERROR_NOT_READY = 0x15;
+        internal const int ERROR_SHARING_VIOLATION = 0x20;
+        internal const int ERROR_HANDLE_EOF = 0x26;
+        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_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;
+        internal const int ERROR_NO_DATA = 0xE8;
+        internal const int ERROR_MORE_DATA = 0xEA;
+        internal const int ERROR_NO_MORE_ITEMS = 0x103;
+        internal const int ERROR_NOT_OWNER = 0x120;
+        internal const int ERROR_TOO_MANY_POSTS = 0x12A;
+        internal const int ERROR_ARITHMETIC_OVERFLOW = 0x216;
+        internal const int ERROR_MUTANT_LIMIT_EXCEEDED = 0x24B;
+        internal const int ERROR_OPERATION_ABORTED = 0x3E3;
+        internal const int ERROR_IO_PENDING = 0x3E5;
+        internal const int ERROR_NO_UNICODE_TRANSLATION = 0x459;
+        internal const int ERROR_NOT_FOUND = 0x490;
+        internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
+        internal const int ERROR_NO_SYSTEM_RESOURCES = 0x5AA;
+        internal const int ERROR_TIMEOUT = 0x000005B4;
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Interop.Libraries.cs

@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+    internal static partial class Libraries
+    {
+        internal const string Advapi32 = "advapi32.dll";
+        internal const string BCrypt = "BCrypt.dll";
+        internal const string Crypt32 = "crypt32.dll";
+        internal const string Kernel32 = "kernel32.dll";
+        internal const string Ole32 = "ole32.dll";
+        internal const string OleAut32 = "oleaut32.dll";
+        internal const string User32 = "user32.dll";
+        internal const string NtDll = "ntdll.dll";
+    }
+}

+ 24 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CREATEFILE2_EXTENDED_PARAMETERS.cs

@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal unsafe struct CREATEFILE2_EXTENDED_PARAMETERS
+        {
+            internal uint dwSize;
+            internal uint dwFileAttributes;
+            internal uint dwFileFlags;
+            internal uint dwSecurityQosFlags;
+            internal SECURITY_ATTRIBUTES* lpSecurityAttributes;
+            internal IntPtr hTemplateFile;
+        }
+    }
+}

+ 16 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CancelIoEx.cs

@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe bool CancelIoEx(SafeHandle handle, NativeOverlapped* lpOverlapped);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CloseHandle.cs

@@ -0,0 +1,15 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool CloseHandle(IntPtr handle);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Constants.cs

@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+    internal static partial class Kernel32
+    {
+        internal const int MAXIMUM_ALLOWED = 0x02000000;
+        internal const int SYNCHRONIZE = 0x00100000;
+        internal const int MUTEX_MODIFY_STATE = 0x00000001;
+        internal const int SEMAPHORE_MODIFY_STATE = 0x00000002;
+        internal const int EVENT_MODIFY_STATE = 0x00000002;
+    }
+}

+ 40 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs

@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        /// <summary>
+        /// WARNING: This method does not implicitly handle long paths. Use CreateFile.
+        /// </summary>
+        [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        private static extern SafeFileHandle CreateFilePrivate(
+            string lpFileName,
+            int dwDesiredAccess,
+            System.IO.FileShare dwShareMode,
+            ref SECURITY_ATTRIBUTES securityAttrs,
+            System.IO.FileMode dwCreationDisposition,
+            int dwFlagsAndAttributes,
+            IntPtr hTemplateFile);
+
+        internal static SafeFileHandle CreateFile(
+            string lpFileName,
+            int dwDesiredAccess,
+            System.IO.FileShare dwShareMode,
+            ref SECURITY_ATTRIBUTES securityAttrs,
+            System.IO.FileMode dwCreationDisposition,
+            int dwFlagsAndAttributes,
+            IntPtr hTemplateFile)
+        {
+            lpFileName = PathInternal.EnsureExtendedPrefixOverMaxPath(lpFileName);
+            return CreateFilePrivate(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+        }
+    }
+}

+ 32 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs

@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, EntryPoint = "CreateFile2", SetLastError = true, CharSet = CharSet.Unicode)]
+        private static extern SafeFileHandle CreateFile2Private(
+            string lpFileName,
+            int dwDesiredAccess,
+            FileShare dwShareMode,
+            FileMode dwCreationDisposition,
+            ref Kernel32.CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams);
+
+        internal static SafeFileHandle CreateFile2(
+            string lpFileName,
+            int dwDesiredAccess,
+            FileShare dwShareMode,
+            FileMode dwCreationDisposition,
+            ref Kernel32.CREATEFILE2_EXTENDED_PARAMETERS pCreateExParams)
+        {
+            lpFileName = PathInternal.EnsureExtendedPrefixOverMaxPath(lpFileName);
+            return CreateFile2Private(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ref pCreateExParams);
+        }
+    }
+}

+ 28 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs

@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Kernel32
+    {
+        internal const uint CREATE_EVENT_INITIAL_SET = 0x2;
+        internal const uint CREATE_EVENT_MANUAL_RESET = 0x1;
+
+        [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool SetEvent(SafeWaitHandle handle);
+
+        [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool ResetEvent(SafeWaitHandle handle);
+
+        [DllImport(Interop.Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string name, uint flags, uint desiredAccess);
+
+        [DllImport(Interop.Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name);
+    }
+}

+ 39 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FILE_INFO_BY_HANDLE_CLASS.cs

@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal enum FILE_INFO_BY_HANDLE_CLASS : uint
+        {
+            FileBasicInfo = 0x0u,
+            FileStandardInfo = 0x1u,
+            FileNameInfo = 0x2u,
+            FileRenameInfo = 0x3u,
+            FileDispositionInfo = 0x4u,
+            FileAllocationInfo = 0x5u,
+            FileEndOfFileInfo = 0x6u,
+            FileStreamInfo = 0x7u,
+            FileCompressionInfo = 0x8u,
+            FileAttributeTagInfo = 0x9u,
+            FileIdBothDirectoryInfo = 0xAu,
+            FileIdBothDirectoryRestartInfo = 0xBu,
+            FileIoPriorityHintInfo = 0xCu,
+            FileRemoteProtocolInfo = 0xDu,
+            FileFullDirectoryInfo = 0xEu,
+            FileFullDirectoryRestartInfo = 0xFu,
+            FileStorageInfo = 0x10u,
+            FileAlignmentInfo = 0x11u,
+            FileIdInfo = 0x12u,
+            FileIdExtdDirectoryInfo = 0x13u,
+            FileIdExtdDirectoryRestartInfo = 0x14u,
+            MaximumFileInfoByHandleClass = 0x15u,
+        }
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileAttributes.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal partial class FileAttributes
+        {
+            internal const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
+            internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
+            internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
+            internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
+        }
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FileTypes.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal partial class FileTypes
+        {
+            internal const int FILE_TYPE_UNKNOWN = 0x0000;
+            internal const int FILE_TYPE_DISK = 0x0001;
+            internal const int FILE_TYPE_CHAR = 0x0002;
+            internal const int FILE_TYPE_PIPE = 0x0003;
+        }
+    }
+}

+ 16 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindClose.cs

@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool FindClose(IntPtr hFindFile);
+    }
+}

+ 43 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FindFirstFileEx.cs

@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        /// <summary>
+        /// WARNING: This method does not implicitly handle long paths. Use FindFirstFile.
+        /// </summary>
+        [DllImport(Libraries.Kernel32, EntryPoint = "FindFirstFileExW", SetLastError = true, CharSet = CharSet.Unicode)]
+        private static extern SafeFindHandle FindFirstFileExPrivate(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, ref WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, int dwAdditionalFlags);
+
+        internal static SafeFindHandle FindFirstFile(string fileName, ref WIN32_FIND_DATA data)
+        {
+            fileName = PathInternal.EnsureExtendedPrefixIfNeeded(fileName);
+
+            // use FindExInfoBasic since we don't care about short name and it has better perf
+            return FindFirstFileExPrivate(fileName, FINDEX_INFO_LEVELS.FindExInfoBasic, ref data, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, 0);
+        }
+
+        internal enum FINDEX_INFO_LEVELS : uint
+        {
+            FindExInfoStandard = 0x0u,
+            FindExInfoBasic = 0x1u,
+            FindExInfoMaxInfoLevel = 0x2u,
+        }
+
+        internal enum FINDEX_SEARCH_OPS : uint
+        {
+            FindExSearchNameMatch = 0x0u,
+            FindExSearchLimitToDirectories = 0x1u,
+            FindExSearchLimitToDevices = 0x2u,
+            FindExSearchMaxSearchOp = 0x3u,
+        }
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FlushFileBuffers.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        internal static extern bool FlushFileBuffers(SafeHandle hHandle);
+    }
+}

+ 88 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FormatMessage.cs

@@ -0,0 +1,88 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
+        private const int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
+        private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
+        private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
+        private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
+        private const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
+
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)]
+        private static extern unsafe int FormatMessage(
+            int dwFlags,
+            IntPtr lpSource,
+            uint dwMessageId,
+            int dwLanguageId,
+            void* lpBuffer,
+            int nSize,
+            IntPtr arguments);
+
+        /// <summary>
+        ///     Returns a string message for the specified Win32 error code.
+        /// </summary>
+        internal static string GetMessage(int errorCode) =>
+            GetMessage(errorCode, IntPtr.Zero);
+
+        internal static unsafe string GetMessage(int errorCode, IntPtr moduleHandle)
+        {
+            int flags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY;
+            if (moduleHandle != IntPtr.Zero)
+            {
+                flags |= FORMAT_MESSAGE_FROM_HMODULE;
+            }
+
+            // First try to format the message into the stack based buffer.  Most error messages willl fit.
+            Span<char> stackBuffer = stackalloc char[256]; // arbitrary stack limit
+            fixed (char* bufferPtr = stackBuffer)
+            {
+                int length = FormatMessage(flags, moduleHandle, unchecked((uint)errorCode), 0, bufferPtr, stackBuffer.Length, IntPtr.Zero);
+                if (length > 0)
+                {
+                    return GetAndTrimString(stackBuffer.Slice(0, length));
+                }
+            }
+
+            // We got back an error.  If the error indicated that there wasn't enough room to store
+            // the error message, then call FormatMessage again, but this time rather than passing in
+            // a buffer, have the method allocate one, which we then need to free.
+            if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                IntPtr nativeMsgPtr = default;
+                try
+                {
+                    int length = FormatMessage(flags | FORMAT_MESSAGE_ALLOCATE_BUFFER, moduleHandle, unchecked((uint)errorCode), 0, &nativeMsgPtr, 0, IntPtr.Zero);
+                    if (length > 0)
+                    {
+                        return GetAndTrimString(new Span<char>((char*)nativeMsgPtr, length));
+                    }
+                }
+                finally
+                {
+                    Marshal.FreeHGlobal(nativeMsgPtr);
+                }
+            }
+
+            // Couldn't get a message, so manufacture one.
+            return string.Format("Unknown error (0x{0:x})", errorCode);
+        }
+
+        private static string GetAndTrimString(Span<char> buffer)
+        {
+            int length = buffer.Length;
+            while (length > 0 && buffer[length - 1] <= 32)
+            {
+                length--; // trim off spaces and non-printable ASCII chars at the end of the resource
+            }
+            return buffer.Slice(0, length).ToString();
+        }
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FreeEnvironmentStrings.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, EntryPoint = "FreeEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        internal static extern unsafe bool FreeEnvironmentStrings(char* lpszEnvironmentBlock);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.FreeLibrary.cs

@@ -0,0 +1,15 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
+        internal static extern bool FreeLibrary(IntPtr hModule);
+    }
+}

+ 24 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCPInfo.cs

@@ -0,0 +1,24 @@
+// 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.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal unsafe struct CPINFO
+        {
+            internal int MaxCharSize;
+
+            internal fixed byte DefaultChar[2 /* MAX_DEFAULTCHAR */];
+            internal fixed byte LeadByte[12 /* MAX_LEADBYTES */];
+        }
+
+        [DllImport(Libraries.Kernel32)]
+        internal static extern unsafe int GetCPInfo(uint codePage, CPINFO* lpCpInfo);
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetEnvironmentStrings.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, EntryPoint = "GetEnvironmentStringsW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        internal static extern unsafe char* GetEnvironmentStrings();
+    }
+}

+ 94 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileAttributesEx.cs

@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        /// <summary>
+        /// WARNING: This method does not implicitly handle long paths. Use GetFileAttributesEx.
+        /// </summary>
+        [DllImport(Libraries.Kernel32, EntryPoint = "GetFileAttributesExW", SetLastError = true, CharSet = CharSet.Unicode)]
+        private static extern bool GetFileAttributesExPrivate(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
+
+        internal static bool GetFileAttributesEx(string name, GET_FILEEX_INFO_LEVELS fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation)
+        {
+            name = PathInternal.EnsureExtendedPrefixOverMaxPath(name);
+            return GetFileAttributesExPrivate(name, fileInfoLevel, ref lpFileInformation);
+        }
+
+        internal enum GET_FILEEX_INFO_LEVELS : uint
+        {
+            GetFileExInfoStandard = 0x0u,
+            GetFileExMaxInfoLevel = 0x1u,
+        }
+
+        internal struct WIN32_FILE_ATTRIBUTE_DATA
+        {
+            internal int dwFileAttributes;
+            internal uint ftCreationTimeLow;
+            internal uint ftCreationTimeHigh;
+            internal uint ftLastAccessTimeLow;
+            internal uint ftLastAccessTimeHigh;
+            internal uint ftLastWriteTimeLow;
+            internal uint ftLastWriteTimeHigh;
+            internal uint fileSizeHigh;
+            internal uint fileSizeLow;
+
+            internal void PopulateFrom(ref WIN32_FIND_DATA findData)
+            {
+                // Copy the information to data
+                dwFileAttributes = (int)findData.dwFileAttributes;
+                ftCreationTimeLow = findData.ftCreationTime.dwLowDateTime;
+                ftCreationTimeHigh = findData.ftCreationTime.dwHighDateTime;
+                ftLastAccessTimeLow = findData.ftLastAccessTime.dwLowDateTime;
+                ftLastAccessTimeHigh = findData.ftLastAccessTime.dwHighDateTime;
+                ftLastWriteTimeLow = findData.ftLastWriteTime.dwLowDateTime;
+                ftLastWriteTimeHigh = findData.ftLastWriteTime.dwHighDateTime;
+                fileSizeHigh = findData.nFileSizeHigh;
+                fileSizeLow = findData.nFileSizeLow;
+            }
+        }
+
+        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+        [BestFitMapping(false)]
+        internal unsafe struct WIN32_FIND_DATA
+        {
+            internal uint dwFileAttributes;
+            internal FILE_TIME ftCreationTime;
+            internal FILE_TIME ftLastAccessTime;
+            internal FILE_TIME ftLastWriteTime;
+            internal uint nFileSizeHigh;
+            internal uint nFileSizeLow;
+            internal uint dwReserved0;
+            internal uint dwReserved1;
+            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+            internal string cFileName;
+            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+            internal string cAlternateFileName;
+        }
+
+        internal struct FILE_TIME
+        {
+            internal uint dwLowDateTime;
+            internal uint dwHighDateTime;
+
+            internal FILE_TIME(long fileTime)
+            {
+                dwLowDateTime = (uint)fileTime;
+                dwHighDateTime = (uint)(fileTime >> 32);
+            }
+
+            internal long ToTicks()
+            {
+                return ((long)dwHighDateTime << 32) + dwLowDateTime;
+            }
+        }
+    }
+}

+ 25 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.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.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool GetFileInformationByHandleEx(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, out FILE_STANDARD_INFO lpFileInformation, uint dwBufferSize);
+
+        internal struct FILE_STANDARD_INFO
+        {
+            internal long AllocationSize;
+            internal long EndOfFile;
+            internal uint NumberOfLinks;
+            internal BOOL DeletePending;
+            internal BOOL Directory;
+        }
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFileType_SafeHandle.cs

@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern int GetFileType(SafeHandle hFile);
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetFullPathNameW.cs

@@ -0,0 +1,18 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        /// <summary>
+        /// WARNING: This method does not implicitly handle long paths. Use GetFullPathName or PathHelper.
+        /// </summary>
+        [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+        internal static extern uint GetFullPathNameW(ref char lpFileName, uint nBufferLength, ref char lpBuffer, IntPtr lpFilePart);
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs

@@ -0,0 +1,18 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        /// <summary>
+        /// WARNING: This method does not implicitly handle long paths. Use GetFullPath/PathHelper.
+        /// </summary>
+        [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+        internal static extern uint GetLongPathNameW(ref char lpszShortPath, ref char lpszLongPath, uint cchBuffer);
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
+        internal static extern uint GetTempFileNameW(ref char lpPathName, string lpPrefixString, uint uUnique, ref char lpTempFileName);
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        internal static extern uint GetTempPathW(int bufferLen, ref char buffer);
+    }
+}

+ 129 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs

@@ -0,0 +1,129 @@
+// 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;
+
+internal static partial class Interop
+{
+    internal static unsafe partial class Kernel32
+    {
+        internal const uint LOCALE_ALLOW_NEUTRAL_NAMES  = 0x08000000; // Flag to allow returning neutral names/lcids for name conversion
+        internal const uint LOCALE_SUPPLEMENTAL         = 0x00000002;
+        internal const uint LOCALE_REPLACEMENT          = 0x00000008;
+        internal const uint LOCALE_NEUTRALDATA          = 0x00000010;
+        internal const uint LOCALE_SPECIFICDATA         = 0x00000020;
+        internal const int  COMPARE_STRING              = 0x0001;
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern unsafe int LCIDToLocaleName(int locale, char *pLocaleName, int cchName, uint dwFlags);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern int LocaleNameToLCID(string lpName, uint dwFlags);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern unsafe int LCMapStringEx(
+                    string lpLocaleName,
+                    uint dwMapFlags,
+                    char* lpSrcStr,
+                    int cchSrc,
+                    void* lpDestStr,
+                    int cchDest,
+                    void* lpVersionInformation,
+                    void* lpReserved,
+                    IntPtr sortHandle);
+
+        [DllImport("kernel32.dll", EntryPoint = "FindNLSStringEx")]
+        internal static extern unsafe int FindNLSStringEx(
+                    char* lpLocaleName,
+                    uint dwFindNLSStringFlags,
+                    char* lpStringSource,
+                    int cchSource,
+                    char* lpStringValue,
+                    int cchValue,
+                    int* pcchFound,
+                    void* lpVersionInformation,
+                    void* lpReserved,
+                    IntPtr sortHandle);
+
+        [DllImport("kernel32.dll", EntryPoint = "CompareStringEx")]
+        internal static extern unsafe int CompareStringEx(
+                    char* lpLocaleName,
+                    uint dwCmpFlags,
+                    char* lpString1,
+                    int cchCount1,
+                    char* lpString2,
+                    int cchCount2,
+                    void* lpVersionInformation,
+                    void* lpReserved,
+                    IntPtr lParam);
+
+        [DllImport("kernel32.dll", EntryPoint = "CompareStringOrdinal")]
+        internal static extern unsafe int CompareStringOrdinal(
+                    char* lpString1,
+                    int cchCount1,
+                    char* lpString2,
+                    int cchCount2,
+                    bool bIgnoreCase);
+
+        [DllImport("kernel32.dll", EntryPoint = "FindStringOrdinal")]
+        internal static extern unsafe int FindStringOrdinal(
+                    uint dwFindStringOrdinalFlags,
+                    char* lpStringSource,
+                    int cchSource,
+                    char* lpStringValue,
+                    int cchValue,
+                    int bIgnoreCase);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern unsafe bool IsNLSDefinedString(
+                    int  Function,
+                    uint dwFlags,
+                    IntPtr lpVersionInformation,
+                    char* lpString,
+                    int cchStr);
+
+#if !ENABLE_WINRT
+        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
+        internal static extern bool GetUserPreferredUILanguages(uint dwFlags, out uint pulNumLanguages, char [] pwszLanguagesBuffer, ref uint pcchLanguagesBuffer);
+#endif //!ENABLE_WINRT
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, void* lpLCData, int cchData);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern bool EnumSystemLocalesEx(EnumLocalesProcEx lpLocaleEnumProcEx, uint dwFlags, void* lParam, IntPtr reserved);
+
+        internal delegate BOOL EnumLocalesProcEx(char* lpLocaleString, uint dwFlags, void* lParam);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern bool EnumTimeFormatsEx(EnumTimeFormatsProcEx lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, void* lParam);
+  
+        internal delegate BOOL EnumTimeFormatsProcEx(char* lpTimeFormatString, void* lParam);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern int GetCalendarInfoEx(string lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, out int lpValue);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern int GetCalendarInfoEx(string lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, IntPtr lpValue);
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern bool EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string lpReserved, uint CalType, void* lParam);
+        
+        internal delegate BOOL EnumCalendarInfoProcExEx(char* lpCalendarInfoString, uint Calendar, IntPtr lpReserved, void* lParam);
+
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct NlsVersionInfoEx
+        {
+            internal int dwNLSVersionInfoSize;
+            internal int dwNLSVersion;
+            internal int dwDefinedVersion;
+            internal int dwEffectiveId;
+            internal Guid guidCustomVersion;
+        }
+        
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern unsafe bool GetNLSVersionEx(int function, string localeName, NlsVersionInfoEx* lpVersionInformation);
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.LoadLibraryEx.cs

@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
+
+        [DllImport(Libraries.Kernel32, EntryPoint = "LoadLibraryExW", CharSet = CharSet.Unicode, SetLastError = true)]
+        internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags);
+    }
+}

+ 20 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.LockFile.cs

@@ -0,0 +1,20 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool LockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
+
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool UnlockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
+    }
+}

+ 11 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MAX_PATH.cs

@@ -0,0 +1,11 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal const int MAX_PATH = 260;
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MUI.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Kernel32
+    {
+        internal const uint MUI_PREFERRED_UI_LANGUAGES = 0x10;
+
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
+        internal static extern unsafe bool GetFileMUIPath(uint dwFlags, string pcwszFilePath, char* pwszLanguage, ref int pcchLanguage, char* pwszFileMUIPath, ref int pcchFileMUIPath, ref long pululEnumerator);
+    }
+}

+ 20 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.MultiByteToWideChar.cs

@@ -0,0 +1,20 @@
+// 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;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32)]
+        internal static extern unsafe int MultiByteToWideChar(
+            uint CodePage, uint dwFlags,
+            byte* lpMultiByteStr, int cbMultiByte,
+            char* lpWideCharStr, int cchWideChar);
+
+        internal const uint MB_PRECOMPOSED = 0x00000001;
+    }
+}

+ 24 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs

@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Kernel32
+    {
+        internal const uint CREATE_MUTEX_INITIAL_OWNER = 0x1;
+
+        [DllImport(Interop.Libraries.Kernel32, EntryPoint = "OpenMutexW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle OpenMutex(uint desiredAccess, bool inheritHandle, string name);
+
+        [DllImport(Interop.Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle CreateMutexEx(IntPtr lpMutexAttributes, string name, uint flags, uint desiredAccess);
+
+        [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool ReleaseMutex(SafeWaitHandle handle);
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "OutputDebugStringW", ExactSpelling = true)]
+        internal static extern void OutputDebugString(string message);
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs

@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int ReadFile(
+            SafeHandle handle,
+            byte* bytes,
+            int numBytesToRead,
+            out int numBytesRead,
+            IntPtr mustBeZero);
+    }
+}

+ 22 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs

@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int ReadFile(
+            SafeHandle handle,
+            byte* bytes,
+            int numBytesToRead,
+            IntPtr numBytesRead_mustBeZero,
+            NativeOverlapped* overlapped);
+    }
+}

+ 17 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.ResolveLocaleName.cs

@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static unsafe partial class Kernel32
+    {
+        internal const int LOCALE_NAME_MAX_LENGTH = 85;
+
+        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+        internal static extern int ResolveLocaleName(string lpNameToResolve, char* lpLocaleName, int cchLocaleName);
+    }
+}

+ 21 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs

@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [StructLayout(LayoutKind.Sequential)]
+        internal struct SECURITY_ATTRIBUTES
+        {
+            internal uint nLength;
+            internal IntPtr lpSecurityDescriptor;
+            internal BOOL bInheritHandle;
+        }
+    }
+}

+ 18 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SecurityOptions.cs

@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        internal partial class SecurityOptions
+        {
+            internal const int SECURITY_SQOS_PRESENT = 0x00100000;
+            internal const int SECURITY_ANONYMOUS = 0 << 16;
+            internal const int SECURITY_IDENTIFICATION = 1 << 16;
+            internal const int SECURITY_IMPERSONATION = 2 << 16;
+            internal const int SECURITY_DELEGATION = 3 << 16;
+        }
+    }
+}

+ 22 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs

@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Kernel32
+    {
+        [DllImport(Interop.Libraries.Kernel32, EntryPoint = "OpenSemaphoreW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle OpenSemaphore(uint desiredAccess, bool inheritHandle, string name);
+        
+        [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode)]
+        internal static extern SafeWaitHandle CreateSemaphoreEx(IntPtr lpSecurityAttributes, int initialCount, int maximumCount, string name, uint flags, uint desiredAccess);
+
+        [DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool ReleaseSemaphore(SafeWaitHandle handle, int releaseCount, out int previousCount);
+    }
+}

+ 15 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SetEndOfFile.cs

@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern bool SetEndOfFile(SafeFileHandle hFile);
+    }
+}

+ 14 - 0
netcore/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.SetEnvironmentVariable.cs

@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+    internal partial class Kernel32
+    {
+        [DllImport(Libraries.Kernel32, EntryPoint = "SetEnvironmentVariableW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        internal static extern bool SetEnvironmentVariable(string lpName, string lpValue);
+    }
+}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels