diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-09-15 12:48:04 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-15 12:48:04 +0300 |
commit | 0d009e60dd6f151c2f480bc85731023447c518da (patch) | |
tree | 5aa7355e98f0ff36167824ce3ef198bd502cec50 | |
parent | caba8d453641ee905acfcb86391eebaa2465f611 (diff) | |
parent | 3ca0b104827cf5e4795aac4e2c0b94084542e0fc (diff) |
Merge pull request #6332 from dotnet/master
Merge master to nmirror
51 files changed, 525 insertions, 747 deletions
diff --git a/DotnetCLIVersion.txt b/DotnetCLIVersion.txt index 5e908d682..6f1c03c6a 100644 --- a/DotnetCLIVersion.txt +++ b/DotnetCLIVersion.txt @@ -1 +1 @@ -2.1.301 +2.1.401
\ No newline at end of file diff --git a/buildscripts/build-packages.cmd b/buildscripts/build-packages.cmd index f62bfc9d2..cc7388708 100644 --- a/buildscripts/build-packages.cmd +++ b/buildscripts/build-packages.cmd @@ -27,5 +27,5 @@ exit /b %ERRORLEVEL% :AfterVarSetup -%_msbuildexe% "%__ProjectDir%\pkg\packages.proj" /m /nologo /flp:v=diag;LogFile=build-packages.log /p:NuPkgRid=%__NugetRuntimeId% /p:OSGroup=%__BuildOS% /p:Configuration=%__BuildType% /p:Platform=%__BuildArch% %__ExtraMsBuildParams% +"%__DotNetCliPath%\dotnet.exe" msbuild "%__ProjectDir%\pkg\packages.proj" /m /nologo /flp:v=diag;LogFile=build-packages.log /p:NuPkgRid=%__NugetRuntimeId% /p:OSGroup=%__BuildOS% /p:Configuration=%__BuildType% /p:Platform=%__BuildArch% %__ExtraMsBuildParams% exit /b %ERRORLEVEL% diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props index 22392cd25..b06165b8a 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props +++ b/src/BuildIntegration/Microsoft.NETCore.Native.Windows.props @@ -40,6 +40,7 @@ See the LICENSE file in the project root for more information. <NativeLibrary Condition="$(NativeCodeGen) == '' and $(NativeLib) != ''" Include="$(IlcPath)\sdk\bootstrapperdll.lib" /> <NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\$(FullRuntimeName).lib" /> <NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)\sdk\System.Private.TypeLoader.Native.lib" /> + <NativeLibrary Condition="$(NativeCodeGen) == '' and '$(ExperimentalJitSupport)' == 'true'" Include="$(IlcPath)\sdk\System.Private.Jit.Native.lib" /> <NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" /> <NativeLibrary Condition="$(NativeCodeGen) == 'cpp'" Include="$(IlcPath)\sdk\PortableRuntime.lib" /> <NativeLibrary Condition="$(NativeCodeGen) == 'wasm'" Include="$(IlcPath)\sdk\bootstrappercpp.lib" /> diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets index 66af195d0..e5d806dce 100644 --- a/src/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets @@ -67,6 +67,8 @@ See the LICENSE file in the project root for more information. <FrameworkLibPath Condition="'$(FrameworkLibPath)' == ''">$(NativeOutputPath)</FrameworkLibPath> <FrameworkObjPath Condition="'$(FrameworkObjPath)' == ''">$(NativeIntermediateOutputPath)</FrameworkObjPath> + <ExperimentalDynamicCodeSupport Condition="'$(ExperimentalInterpreterSupport)' == 'true' or '$(ExperimentalJitSupport)' == 'true'">true</ExperimentalDynamicCodeSupport> + <SharedLibrary Condition="'$(OS)' == 'Windows_NT'">$(FrameworkLibPath)\Framework$(LibFileExt)</SharedLibrary> <SharedLibrary Condition="'$(OS)' != 'Windows_NT'">$(FrameworkLibPath)\libframework$(LibFileExt)</SharedLibrary> <IlcDynamicBuildPropertyDependencies Condition="'$(IlcCalledViaPackage)' == 'true'">SetupProperties</IlcDynamicBuildPropertyDependencies> @@ -81,17 +83,19 @@ See the LICENSE file in the project root for more information. <ItemGroup> <AutoInitializedAssemblies Include="System.Private.CoreLib" /> <AutoInitializedAssemblies Include="System.Private.DeveloperExperience.Console" /> - <AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" /> + <AutoInitializedAssemblies Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="System.Private.Interpreter" /> + <AutoInitializedAssemblies Condition="'$(ExperimentalJitSupport)' == 'true'" Include="System.Private.Jit" /> </ItemGroup> - <ItemGroup Condition="'$(ExperimentalInterpreterSupport)' != 'true'"> + <ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' != 'true'"> + <AutoInitializedAssemblies Include="System.Private.StackTraceMetadata" /> <AutoInitializedAssemblies Include="System.Private.TypeLoader" /> <AutoInitializedAssemblies Include="System.Private.Reflection.Execution" /> <AutoInitializedAssemblies Include="System.Private.Interop" /> </ItemGroup> - <ItemGroup Condition="'$(ExperimentalInterpreterSupport)' == 'true'"> - <AutoInitializedAssemblies Include="System.Private.Interpreter" /> + <ItemGroup Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'"> + <AutoInitializedAssemblies Include="System.Private.StackTraceMetadata.Experimental" /> <AutoInitializedAssemblies Include="System.Private.TypeLoader.Experimental" /> <AutoInitializedAssemblies Include="System.Private.Reflection.Execution.Experimental" /> <AutoInitializedAssemblies Include="System.Private.Interop.Experimental" /> @@ -180,7 +184,7 @@ See the LICENSE file in the project root for more information. <IlcArg Condition="$(OutputType) == 'Library' and $(NativeLib) != ''" Include="--nativelib" /> <IlcArg Condition="$(ExportsFile) != ''" Include="--exportsfile:$(ExportsFile)" /> <ILcArg Condition="'$(Platform)' == 'wasm'" Include="--wasm" /> - <ILcArg Condition="'$(ExperimentalInterpreterSupport)' == 'true'" Include="--nometadatablocking" /> + <ILcArg Condition="'$(ExperimentalDynamicCodeSupport)' == 'true'" Include="--nometadatablocking" /> <IlcArg Include="@(AutoInitializedAssemblies->'--initassembly:%(Identity)')" /> <IlcArg Include="@(AppContextSwitchOverrides->'--appcontextswitch:%(Identity)')" /> <IlcArg Condition="$(ServerGarbageCollection) != ''" Include="--runtimeopt:RH_UseServerGC=1" /> diff --git a/src/Common/src/Interop/Windows/Interop.Libraries.cs b/src/Common/src/Interop/Windows/Interop.Libraries.cs index 8536bc367..68a50eadd 100644 --- a/src/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/Common/src/Interop/Windows/Interop.Libraries.cs @@ -6,9 +6,6 @@ internal static partial class Interop { internal static partial class Libraries { - internal const string CoreFile_L1 = "api-ms-win-core-file-l1-1-0.dll"; - internal const string CoreFile_L1_2 = "api-ms-win-core-file-l1-2-0.dll"; - internal const string CoreFile_L2 = "api-ms-win-core-file-l2-1-0.dll"; internal const string ErrorHandling = "api-ms-win-core-errorhandling-l1-1-0.dll"; internal const string Handle = "api-ms-win-core-handle-l1-1-0.dll"; internal const string IO = "api-ms-win-core-io-l1-1-0.dll"; @@ -17,7 +14,6 @@ internal static partial class Interop internal const string ProcessThreads = "api-ms-win-core-processthreads-l1-1-0.dll"; internal const string RealTime = "api-ms-win-core-realtime-l1-1-0.dll"; internal const string SysInfo = "api-ms-win-core-sysinfo-l1-2-0.dll"; - internal const string Registry_L1 = "api-ms-win-core-registry-l1-1-0.dll"; internal const string ThreadPool = "api-ms-win-core-threadpool-l1-2-0.dll"; internal const string Localization = "api-ms-win-core-localization-l1-2-1.dll"; } diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegistryOptions.cs b/src/Common/src/Interop/Windows/mincore/Interop.RegistryOptions.cs deleted file mode 100644 index c5133fd30..000000000 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegistryOptions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -internal partial class Interop -{ - internal partial class mincore - { - internal partial 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 partial 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; - } - } -} diff --git a/src/Common/src/Interop/Windows/ole32/Interop.CoInitializeEx.cs b/src/Common/src/Interop/Windows/ole32/Interop.CoInitializeEx.cs new file mode 100644 index 000000000..f953d5ec4 --- /dev/null +++ b/src/Common/src/Interop/Windows/ole32/Interop.CoInitializeEx.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.CompilerServices; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Ole32 + { + internal const uint COINIT_APARTMENTTHREADED = 2; + internal const uint COINIT_MULTITHREADED = 0; + + [DllImport(Interop.Libraries.Ole32, ExactSpelling = true)] + internal extern static int CoInitializeEx(IntPtr reserved, uint dwCoInit); + } +} diff --git a/src/Common/src/Interop/Windows/ole32/Interop.CoUninitialize.cs b/src/Common/src/Interop/Windows/ole32/Interop.CoUninitialize.cs new file mode 100644 index 000000000..ae0836688 --- /dev/null +++ b/src/Common/src/Interop/Windows/ole32/Interop.CoUninitialize.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.CompilerServices; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Ole32 + { + [DllImport(Interop.Libraries.Ole32, ExactSpelling = true)] + internal extern static int CoUninitialize(); + } +} diff --git a/src/JitInterface/src/CorInfoImpl.cs b/src/JitInterface/src/CorInfoImpl.cs index 13d2ccac4..b02092b30 100644 --- a/src/JitInterface/src/CorInfoImpl.cs +++ b/src/JitInterface/src/CorInfoImpl.cs @@ -42,6 +42,12 @@ namespace Internal.JitInterface ARM = 0x01c4, } +#if SUPPORT_JIT + private const string JitSupportLibrary = "*"; +#else + private const string JitSupportLibrary = "jitinterface"; +#endif + private IntPtr _jit; private IntPtr _unmanagedCallbacks; // array of pointers to JIT-EE interface callbacks @@ -55,7 +61,7 @@ namespace Internal.JitInterface [DllImport("clrjitilc", CallingConvention=CallingConvention.StdCall)] private extern static IntPtr getJit(); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static IntPtr GetJitHost(IntPtr configProvider); // @@ -68,15 +74,15 @@ namespace Internal.JitInterface return _this; } - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static CorJitResult JitCompileMethod(out IntPtr exception, IntPtr jit, IntPtr thisHandle, IntPtr callbacks, ref CORINFO_METHOD_INFO info, uint flags, out IntPtr nativeEntry, out uint codeSize); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static uint GetMaxIntrinsicSIMDVectorLength(IntPtr jit, CORJIT_FLAGS* flags); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)]string message, int messageLength); private IntPtr AllocException(Exception ex) @@ -93,10 +99,10 @@ namespace Internal.JitInterface return nativeException; } - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static void FreeException(IntPtr obj); - [DllImport("jitinterface")] + [DllImport(JitSupportLibrary)] private extern static char* GetExceptionMessage(IntPtr obj); private Compilation _compilation; diff --git a/src/Native/jitinterface/CMakeLists.txt b/src/Native/jitinterface/CMakeLists.txt index 46c071c8a..5262e0d8c 100644 --- a/src/Native/jitinterface/CMakeLists.txt +++ b/src/Native/jitinterface/CMakeLists.txt @@ -7,15 +7,23 @@ set(NATIVE_SOURCES corinfoexception.cpp ) +set (JIT_SOURCES + CodeHeap.cpp + JITCodeManager.cpp + ../Runtime/coreclr/GCInfoDecoder.cpp +) + if(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64) - set(NATIVE_SOURCES ${NATIVE_SOURCES} - CodeHeap.cpp - JITCodeManager.cpp - ../Runtime/coreclr/GCInfoDecoder.cpp - ) add_definitions(-DGCINFODECODER_NO_EE) add_definitions(-DFEATURE_REDHAWK) + add_definitions(-DFEATURE_SINGLE_MODULE_RUNTIME) + + add_library(System.Private.Jit.Native + STATIC + ${NATIVE_SOURCES} + ${JIT_SOURCES} + ) endif(WIN32 AND CLR_CMAKE_PLATFORM_ARCH_AMD64) add_library(jitinterface @@ -27,4 +35,5 @@ install (TARGETS jitinterface DESTINATION tools) if(WIN32) target_link_libraries(jitinterface ntdll.lib) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/jitinterface.pdb DESTINATION tools) + install (TARGETS System.Private.Jit.Native DESTINATION sdk) endif(WIN32) diff --git a/src/Native/jitinterface/CodeHeap.cpp b/src/Native/jitinterface/CodeHeap.cpp index 1adc206ea..468bd2588 100644 --- a/src/Native/jitinterface/CodeHeap.cpp +++ b/src/Native/jitinterface/CodeHeap.cpp @@ -18,13 +18,23 @@ static void *s_topAddress = nullptr; static DWORD s_pageSize = 0; extern HMODULE s_hRuntime; +#if FEATURE_SINGLE_MODULE_RUNTIME +extern "C" void RhpNewArray(); +#endif + void InitMemoryStatics() { std::call_once(s_staticInit, []() { HMODULE module = s_hRuntime; if (module != NULL) + { +#if FEATURE_SINGLE_MODULE_RUNTIME + s_mrtAddr = &RhpNewArray; +#else s_mrtAddr = GetProcAddress(module, "RhpNewArray"); +#endif + } assert(s_mrtAddr != nullptr); diff --git a/src/Native/jitinterface/JITCodeManager.cpp b/src/Native/jitinterface/JITCodeManager.cpp index 198671f14..11a1088be 100644 --- a/src/Native/jitinterface/JITCodeManager.cpp +++ b/src/Native/jitinterface/JITCodeManager.cpp @@ -46,14 +46,24 @@ HMODULE s_hRuntime = NULL; pfnRegisterCodeManager s_pfnRegisterCodeManager; pfnUnregisterCodeManager s_pfnUnregisterCodeManager; +#if FEATURE_SINGLE_MODULE_RUNTIME +extern "C" bool RegisterCodeManager(ICodeManager * pCodeManager, PTR_VOID pvStartRange, UInt32 cbRange); +extern "C" void UnregisterCodeManager(ICodeManager * pCodeManager); +#endif + bool InitializeCodeManagerRuntime() { std::call_once(s_RuntimeInit, []() { if (s_hRuntime != NULL) { +#if FEATURE_SINGLE_MODULE_RUNTIME + s_pfnRegisterCodeManager = &RegisterCodeManager; + s_pfnUnregisterCodeManager = &UnregisterCodeManager; +#else s_pfnRegisterCodeManager = (pfnRegisterCodeManager)GetProcAddress(s_hRuntime, "RegisterCodeManager"); s_pfnUnregisterCodeManager = (pfnUnregisterCodeManager)GetProcAddress(s_hRuntime, "UnregisterCodeManager"); +#endif } }); @@ -259,7 +269,7 @@ bool JITCodeManager::Initialize() // Note that main method bodies will not have an entry in the map. PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION mainMethod, DWORD beginAddr, DWORD endAddr, DWORD unwindData) { - ReaderWriterLock::WriteHolder lh(&m_lock); + SlimReaderWriterLock::WriteHolder lh(&m_lock); m_runtimeFunctions.push_back(RUNTIME_FUNCTION()); PTR_RUNTIME_FUNCTION method = &m_runtimeFunctions.back(); @@ -278,7 +288,7 @@ PTR_RUNTIME_FUNCTION JITCodeManager::AllocRuntimeFunction(PTR_RUNTIME_FUNCTION m void JITCodeManager::UpdateRuntimeFunctionTable() { - ReaderWriterLock::WriteHolder lh(&m_lock); + SlimReaderWriterLock::WriteHolder lh(&m_lock); PTR_RUNTIME_FUNCTION pFunctionTable = &m_runtimeFunctions[0]; DWORD nEntryCount = (DWORD)m_runtimeFunctions.size(); @@ -381,7 +391,7 @@ bool JITCodeManager::FindMethodInfo(PTR_VOID ControlPC, if (RelativePC >= m_cbRange) return false; - ReaderWriterLock::ReadHolder lh(&m_lock); + SlimReaderWriterLock::ReadHolder lh(&m_lock); int MethodIndex = LookupUnwindInfoForMethod((UInt32)RelativePC, m_pRuntimeFunctionTable, 0, m_nRuntimeFunctionTable - 1); @@ -420,7 +430,7 @@ bool JITCodeManager::IsFunclet(MethodInfo * pMethInfo) JITMethodInfo * pMethodInfo = (JITMethodInfo *)pMethInfo; // A funclet will have an entry in funclet to main method map - ReaderWriterLock::ReadHolder lh(&m_lock); + SlimReaderWriterLock::ReadHolder lh(&m_lock); return m_FuncletToMainMethodMap.find(pMethodInfo->runtimeFunction.BeginAddress) != m_FuncletToMainMethodMap.end(); } diff --git a/src/Native/jitinterface/JITCodeManager.h b/src/Native/jitinterface/JITCodeManager.h index aeff8bc89..991cb0d65 100644 --- a/src/Native/jitinterface/JITCodeManager.h +++ b/src/Native/jitinterface/JITCodeManager.h @@ -51,19 +51,19 @@ typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO; typedef DPTR(union _UNWIND_CODE) PTR_UNWIND_CODE; #endif // target_amd64 -class ReaderWriterLock : private SRWLOCK +class SlimReaderWriterLock : private SRWLOCK { public: - ReaderWriterLock() + SlimReaderWriterLock() { ::InitializeSRWLock(this); } class ReadHolder { - ReaderWriterLock * m_pLock; + SlimReaderWriterLock * m_pLock; public: - ReadHolder(ReaderWriterLock * pLock) + ReadHolder(SlimReaderWriterLock * pLock) : m_pLock(pLock) { ::AcquireSRWLockShared(m_pLock); @@ -77,10 +77,10 @@ public: class WriteHolder { - ReaderWriterLock * m_pLock; + SlimReaderWriterLock * m_pLock; public: - WriteHolder(ReaderWriterLock * pLock) + WriteHolder(SlimReaderWriterLock * pLock) : m_pLock(pLock) { ::AcquireSRWLockExclusive(m_pLock); @@ -167,7 +167,7 @@ class JITCodeManager : ICodeManager UInt32 m_cbRange; // lock to protect m_runtimeFunctions and m_FuncletToMainMethodMap - ReaderWriterLock m_lock; + SlimReaderWriterLock m_lock; std::vector<RUNTIME_FUNCTION> m_runtimeFunctions; PTR_RUNTIME_FUNCTION m_pRuntimeFunctionTable; diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegCreateKeyEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs index b1ccf69b9..e5219064b 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegCreateKeyEx.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegCreateKeyEx.cs @@ -8,11 +8,11 @@ using System.Runtime.InteropServices; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { // Note: RegCreateKeyEx won't set the last error on failure - it returns // an error code if it fails. - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegCreateKeyExW")] internal static extern int RegCreateKeyEx( SafeRegistryHandle hKey, string lpSubKey, @@ -20,7 +20,7 @@ internal partial class Interop string lpClass, int dwOptions, int samDesired, - ref Kernel32.SECURITY_ATTRIBUTES secAttrs, + ref Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs, out SafeRegistryHandle hkResult, out int lpdwDisposition); } diff --git a/src/Common/src/Interop/Windows/advapi32/Interop.RegSetValueEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs index 59e038d95..4429515cd 100644 --- a/src/Common/src/Interop/Windows/advapi32/Interop.RegSetValueEx.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteKeyEx.cs @@ -2,16 +2,15 @@ // 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 Microsoft.Win32; -using Microsoft.Win32.SafeHandles; internal partial class Interop { internal partial class Advapi32 { - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegSetValueExW")] - internal static extern int RegSetValueEx(SafeRegistryHandle hKey, string lpValueName, int Reserved, RegistryValueKind dwType, string lpData, int cbData); + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteKeyExW")] + internal static extern int RegDeleteKeyEx(SafeRegistryHandle hKey, string lpSubKey, int samDesired, int Reserved); } } diff --git a/src/Common/src/Interop/Windows/advapi32/Interop.RegDeleteValue.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs index 2597b23d0..b8044bc79 100644 --- a/src/Common/src/Interop/Windows/advapi32/Interop.RegDeleteValue.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegDeleteValue.cs @@ -2,15 +2,15 @@ // 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 Microsoft.Win32.SafeHandles; internal partial class Interop { internal partial class Advapi32 { - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegDeleteValueW")] internal static extern int RegDeleteValue(SafeRegistryHandle hKey, string lpValueName); } } diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegEnumKeyEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs index 6196c98b0..bedf28277 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegEnumKeyEx.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumKeyEx.cs @@ -9,13 +9,13 @@ using System.Text; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumKeyExW")] internal static extern unsafe int RegEnumKeyEx( SafeRegistryHandle hKey, int dwIndex, - char* lpName, + char[] lpName, ref int lpcbName, int[] lpReserved, [Out]StringBuilder lpClass, diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegEnumValue.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumValue.cs index 6d88c517c..e02ba98fe 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegEnumValue.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegEnumValue.cs @@ -8,13 +8,13 @@ using System.Runtime.InteropServices; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegEnumValueW")] internal static extern unsafe int RegEnumValue( SafeRegistryHandle hKey, int dwIndex, - char* lpValueName, + char[] lpValueName, ref int lpcbValueName, IntPtr lpReserved_MustBeZero, int[] lpType, diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegFlushKey.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegFlushKey.cs index 25f8ff240..8f72798f8 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegFlushKey.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegFlushKey.cs @@ -7,9 +7,9 @@ using System.Runtime.InteropServices; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1)] + [DllImport(Libraries.Advapi32)] internal static extern int RegFlushKey(SafeRegistryHandle hKey); } } diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegOpenKeyEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs index 9e8d9382f..86b6bcae2 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegOpenKeyEx.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegOpenKeyEx.cs @@ -8,9 +8,9 @@ using System.Runtime.InteropServices; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] internal static extern int RegOpenKeyEx( SafeRegistryHandle hKey, string lpSubKey, @@ -19,7 +19,7 @@ internal partial class Interop out SafeRegistryHandle hkResult); - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegOpenKeyExW")] internal static extern int RegOpenKeyEx( IntPtr hKey, string lpSubKey, diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegQueryInfoKey.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryInfoKey.cs index 19a688440..2df209288 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegQueryInfoKey.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryInfoKey.cs @@ -9,9 +9,9 @@ using System.Text; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryInfoKeyW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryInfoKeyW")] internal static extern int RegQueryInfoKey( SafeRegistryHandle hKey, [Out]StringBuilder lpClass, diff --git a/src/Common/src/Interop/Windows/mincore/Interop.RegQueryValueEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs index 8c748aa67..c6a879817 100644 --- a/src/Common/src/Interop/Windows/mincore/Interop.RegQueryValueEx.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegQueryValueEx.cs @@ -9,9 +9,9 @@ using System.Text; internal partial class Interop { - internal partial class mincore + internal partial class Advapi32 { - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string lpValueName, @@ -20,7 +20,7 @@ internal partial class Interop [Out] byte[] lpData, ref int lpcbData); - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string lpValueName, @@ -29,7 +29,7 @@ internal partial class Interop ref int lpData, ref int lpcbData); - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string lpValueName, @@ -38,7 +38,7 @@ internal partial class Interop ref long lpData, ref int lpcbData); - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string lpValueName, @@ -47,7 +47,7 @@ internal partial class Interop [Out] char[] lpData, ref int lpcbData); - [DllImport(Libraries.Registry_L1, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] + [DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, BestFitMapping = false, EntryPoint = "RegQueryValueExW")] internal static extern int RegQueryValueEx( SafeRegistryHandle hKey, string lpValueName, diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs new file mode 100644 index 000000000..d46f84809 --- /dev/null +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Advapi32/Interop.RegSetValueEx.cs @@ -0,0 +1,59 @@ +// 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; +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, + RegistryValueKind 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, + RegistryValueKind 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, + RegistryValueKind 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, + RegistryValueKind 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, + RegistryValueKind dwType, + string lpData, + int cbData); + } +} diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.RegistryView.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.RegistryView.cs deleted file mode 100644 index 2e6786892..000000000 --- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.RegistryView.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -internal partial class Interop -{ - internal partial class Kernel32 - { - internal partial class RegistryView - { - internal const int KEY_WOW64_64KEY = 0x0100; - internal const int KEY_WOW64_32KEY = 0x0200; - } - } -} diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryOptions.cs b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryOptions.cs index 90b6a3dd7..201a6df0e 100644 --- a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryOptions.cs +++ b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryOptions.cs @@ -14,7 +14,7 @@ namespace Microsoft.Win32 #endif enum RegistryOptions { - None = Interop.mincore.RegistryOptions.REG_OPTION_NON_VOLATILE, // 0x0000 - Volatile = Interop.mincore.RegistryOptions.REG_OPTION_VOLATILE, // 0x0001 + None = Interop.Advapi32.RegistryOptions.REG_OPTION_NON_VOLATILE, // 0x0000 + Volatile = Interop.Advapi32.RegistryOptions.REG_OPTION_VOLATILE, // 0x0001 }; } diff --git a/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryValueOptions.cs b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryValueOptions.cs new file mode 100644 index 000000000..7d9b6c403 --- /dev/null +++ b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryValueOptions.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; + +namespace Microsoft.Win32 +{ + [Flags] +#if REGISTRY_ASSEMBLY + public +#else + internal +#endif + enum RegistryValueOptions + { + None = 0, + DoNotExpandEnvironmentNames = 1 + } +} diff --git a/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryView.cs b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryView.cs index 3cc4a7878..0d6b3038e 100644 --- a/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryView.cs +++ b/src/System.Private.CoreLib/shared/Microsoft/Win32/RegistryView.cs @@ -14,7 +14,7 @@ namespace Microsoft.Win32 enum RegistryView { Default = 0, // 0x0000 operate on the default registry view - Registry64 = Interop.Kernel32.RegistryView.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view - Registry32 = Interop.Kernel32.RegistryView.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view + Registry64 = Interop.Advapi32.RegistryView.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view + Registry32 = Interop.Advapi32.RegistryView.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view }; } diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems index b2db71d75..769b21609 100644 --- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems @@ -801,27 +801,39 @@ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Windows.cs" /> </ItemGroup> <ItemGroup Condition="$(TargetsWindows) and '$(EnableWinRT)' != 'true'"> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\NtDll\NtQueryInformationFile.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegCloseKey.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegCreateKeyEx.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegDeleteKeyEx.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegDeleteValue.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegEnumKeyEx.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegEnumValue.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegFlushKey.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegistryConstants.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.RegistryView.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Win32.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Win32.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegOpenKeyEx.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegQueryInfoKey.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegQueryValueEx.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegSetValueEx.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\Registry.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryHive.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryOptions.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryValueKind.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryValueOptions.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\RegistryView.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeRegistryHandle.Windows.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegCloseKey.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FreeLibrary.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\Security\AccessControl\RegistryRights.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FreeLibrary.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.MUI.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.TimeZone.Registry.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\NtDll\NtQueryInformationFile.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\User32\Interop.Constants.cs" /> - <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\User32\Interop.SendMessageTimeout.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\User32\Interop.LoadString.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\User32\Interop.SendMessageTimeout.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Win32.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.Win32.cs" /> </ItemGroup> <ItemGroup Condition="$(TargetsWindows) and '$(EnableWinRT)' == 'true'"> <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.WinRT.cs" /> diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs index 61e06914c..c94ac0ae5 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs @@ -311,7 +311,7 @@ namespace System.Globalization break; default: const string unsupportedDateFieldSymbols = "YuUrQqwWDFg"; - Debug.Assert(unsupportedDateFieldSymbols.IndexOf(input[index]) == -1, + Debug.Assert(!unsupportedDateFieldSymbols.Contains(input[index]), string.Format(CultureInfo.InvariantCulture, "Encountered an unexpected date field symbol '{0}' from ICU which has no known corresponding .NET equivalent.", input[index])); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs index fda239c51..5eb9f44f8 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs @@ -2268,7 +2268,7 @@ namespace System.Globalization for (int i = startIndex; i < format.Length; ++i) { // See if we have a time Part - if (!inQuote && timeParts.IndexOf(format[i]) != -1) + if (!inQuote && timeParts.Contains(format[i])) { return i; } diff --git a/src/System.Private.CoreLib/shared/System/Guid.cs b/src/System.Private.CoreLib/shared/System/Guid.cs index c57d3c4d9..6e6ec067a 100644 --- a/src/System.Private.CoreLib/shared/System/Guid.cs +++ b/src/System.Private.CoreLib/shared/System/Guid.cs @@ -449,7 +449,7 @@ namespace System } // Check for braces - bool bracesExistInString = (guidString.IndexOf('{') >= 0); + bool bracesExistInString = guidString.Contains('{'); if (bracesExistInString) { @@ -471,7 +471,7 @@ namespace System } // Check for parenthesis - bool parenthesisExistInString = (guidString.IndexOf('(') >= 0); + bool parenthesisExistInString = guidString.Contains('('); if (parenthesisExistInString) { diff --git a/src/System.Private.CoreLib/shared/System/HResults.cs b/src/System.Private.CoreLib/shared/System/HResults.cs index c242389db..4a5ec0d63 100644 --- a/src/System.Private.CoreLib/shared/System/HResults.cs +++ b/src/System.Private.CoreLib/shared/System/HResults.cs @@ -124,5 +124,6 @@ namespace System internal const int RO_E_CLOSED = unchecked((int)0x80000013); internal const int TYPE_E_TYPEMISMATCH = unchecked((int)0x80028CA0); internal const int CO_E_NOTINITIALIZED = unchecked((int)0x800401F0); + internal const int RPC_E_CHANGED_MODE = unchecked((int)0x80010106); } } diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs index f364b84df..ecf71e612 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs @@ -23,7 +23,7 @@ namespace System.IO if (path.Length == 0) throw new ArgumentException(SR.Arg_PathEmpty, nameof(path)); - if (path.IndexOf('\0') != -1) + if (path.Contains('\0')) throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path)); // Expand with current directory if necessary diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs index 1c27e0cf1..ddfd7966b 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs @@ -47,7 +47,7 @@ namespace System.IO // Embedded null characters are the only invalid character case we trully care about. // This is because the nulls will signal the end of the string to Win32 and therefore have // unpredictable results. - if (path.IndexOf('\0') != -1) + if (path.Contains('\0')) throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path)); if (PathInternal.IsExtended(path.AsSpan())) diff --git a/src/System.Private.CoreLib/shared/System/Security/AccessControl/RegistryRights.cs b/src/System.Private.CoreLib/shared/System/Security/AccessControl/RegistryRights.cs new file mode 100644 index 000000000..729e2f6b5 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Security/AccessControl/RegistryRights.cs @@ -0,0 +1,42 @@ +// 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; + +namespace System.Security.AccessControl +{ + // We derived this enum from the definitions of KEY_READ and such from + // winnt.h and from MSDN, plus some experimental validation with regedit. + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry_key_security_and_access_rights.asp + [Flags] +#if REGISTRY_ASSEMBLY + public +#else + internal +#endif + enum RegistryRights + { + // No None field - An ACE with the value 0 cannot grant nor deny. + QueryValues = Interop.Advapi32.RegistryOperations.KEY_QUERY_VALUE, // 0x0001 query the values of a registry key + SetValue = Interop.Advapi32.RegistryOperations.KEY_SET_VALUE, // 0x0002 create, delete, or set a registry value + CreateSubKey = Interop.Advapi32.RegistryOperations.KEY_CREATE_SUB_KEY, // 0x0004 required to create a subkey of a specific key + EnumerateSubKeys = Interop.Advapi32.RegistryOperations.KEY_ENUMERATE_SUB_KEYS, // 0x0008 required to enumerate sub keys of a key + Notify = Interop.Advapi32.RegistryOperations.KEY_NOTIFY, // 0x0010 needed to request change notifications + CreateLink = Interop.Advapi32.RegistryOperations.KEY_CREATE_LINK, // 0x0020 reserved for system use + /// + /// The Windows Kernel team agrees that it was a bad design to expose the WOW64_n options as permissions. + /// in the .NET Framework these options are exposed via the RegistryView enum + /// + /// Reg64 = Interop.Advapi32.RegistryOptions.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view + /// Reg32 = Interop.Advapi32.RegistryOptions.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view + ExecuteKey = ReadKey, + ReadKey = Interop.Advapi32.RegistryOperations.STANDARD_RIGHTS_READ | QueryValues | EnumerateSubKeys | Notify, + WriteKey = Interop.Advapi32.RegistryOperations.STANDARD_RIGHTS_WRITE | SetValue | CreateSubKey, + Delete = 0x10000, + ReadPermissions = 0x20000, + ChangePermissions = 0x40000, + TakeOwnership = 0x80000, + FullControl = 0xF003F | Interop.Advapi32.RegistryOperations.STANDARD_RIGHTS_READ | Interop.Advapi32.RegistryOperations.STANDARD_RIGHTS_WRITE + } +} diff --git a/src/System.Private.CoreLib/shared/System/SpanHelpers.T.cs b/src/System.Private.CoreLib/shared/System/SpanHelpers.T.cs index 20fdc616d..d6f45d226 100644 --- a/src/System.Private.CoreLib/shared/System/SpanHelpers.T.cs +++ b/src/System.Private.CoreLib/shared/System/SpanHelpers.T.cs @@ -51,7 +51,7 @@ namespace System } // Adapted from IndexOf(...) - public static unsafe bool Contains<T>(ref T searchSpace, T value, int length) + public static bool Contains<T>(ref T searchSpace, T value, int length) where T : IEquatable<T> { Debug.Assert(length >= 0); diff --git a/src/System.Private.CoreLib/shared/System/String.Searching.cs b/src/System.Private.CoreLib/shared/System/String.Searching.cs index 857d64eec..7660c5225 100644 --- a/src/System.Private.CoreLib/shared/System/String.Searching.cs +++ b/src/System.Private.CoreLib/shared/System/String.Searching.cs @@ -22,10 +22,7 @@ namespace System return (IndexOf(value, comparisonType) >= 0); } - public bool Contains(char value) - { - return IndexOf(value) != -1; - } + public bool Contains(char value) => SpanHelpers.Contains(ref _firstChar, value, Length); public bool Contains(char value, StringComparison comparisonType) { diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Unix.cs b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Unix.cs index 4d4406027..bc3a042eb 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Unix.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Unix.cs @@ -144,6 +144,14 @@ namespace Internal.Runtime.Augments return IntPtr.Zero; } + private void InitializeComOnNewThread() + { + } + + internal static void InitializeCom() + { + } + public void Interrupt() => WaitSubsystem.Interrupt(this); internal static void UninterruptibleSleep0() => WaitSubsystem.UninterruptibleSleep0(); private static void SleepInternal(int millisecondsTimeout) => WaitSubsystem.Sleep(millisecondsTimeout); diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Windows.cs b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Windows.cs index 4105dff16..e9fe5485b 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Windows.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.Windows.cs @@ -21,8 +21,13 @@ namespace Internal.Runtime.Augments [ThreadStatic] private static ApartmentType t_apartmentType; + [ThreadStatic] + private static bool t_comInitializedByUs; + private SafeWaitHandle _osHandle; + private ApartmentState _initialAppartmentState = ApartmentState.Unknown; + /// <summary> /// Used by <see cref="WaitHandle"/>'s multi-wait functions /// </summary> @@ -286,7 +291,11 @@ namespace Internal.Runtime.Augments public ApartmentState GetApartmentState() { if (this != CurrentThread) - throw new InvalidOperationException(SR.Thread_Operation_RequiresCurrentThread); + { + if (HasStarted()) + throw new ThreadStateException(); + return _initialAppartmentState; + } switch (GetCurrentApartmentType()) { @@ -299,8 +308,81 @@ namespace Internal.Runtime.Augments } } + public bool TrySetApartmentState(ApartmentState state) + { + if (this != CurrentThread) + { + using (LockHolder.Hold(_lock)) + { + if (HasStarted()) + throw new ThreadStateException(); + _initialAppartmentState = state; + return true; + } + } + + if (state != ApartmentState.Unknown) + { + InitializeCom(state); + } + else + { + UninitializeCom(); + } + + // Clear the cache and check whether new state matches the desired state + t_apartmentType = ApartmentType.Unknown; + return state == GetApartmentState(); + } + + private void InitializeComOnNewThread() + { + InitializeCom(_initialAppartmentState); + } + + internal static void InitializeCom(ApartmentState state = ApartmentState.MTA) + { + if (t_comInitializedByUs) + return; + +#if ENABLE_WINRT + int hr = Interop.WinRT.RoInitialize( + (state == ApartmentState.STA) ? Interop.WinRT.RO_INIT_SINGLETHREADED + : Interop.WinRT.RO_INIT_MULTITHREADED); +#else + int hr = Interop.Ole32.CoInitializeEx(IntPtr.Zero, + (state == ApartmentState.STA) ? Interop.Ole32.COINIT_APARTMENTTHREADED + : Interop.Ole32.COINIT_MULTITHREADED); +#endif + // RPC_E_CHANGED_MODE indicates this thread has been already initialized with a different + // concurrency model. We stay away and let whoever else initialized the COM to be in control. + if (hr == HResults.RPC_E_CHANGED_MODE) + return; + if (hr < 0) + throw new OutOfMemoryException(); + + t_comInitializedByUs = true; + + // If the thread has already been CoInitialized to the proper mode, then + // we don't want to leave an outstanding CoInit so we CoUninit. + if (hr > 0) + UninitializeCom(); + } + + private static void UninitializeCom() + { + if (!t_comInitializedByUs) + return; + +#if ENABLE_WINRT + Interop.WinRT.RoUninitialize(); +#else + Interop.Ole32.CoUninitialize(); +#endif + t_comInitializedByUs = false; + } + // TODO: https://github.com/dotnet/corefx/issues/20766 - public bool TrySetApartmentState(ApartmentState state) { throw new PlatformNotSupportedException(); } public void DisableComObjectEagerCleanup() { } public void Interrupt() { throw new PlatformNotSupportedException(); } diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs index 4935750d5..b3e9a14fe 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs @@ -112,7 +112,7 @@ namespace Internal.Runtime.Augments if (threadPoolThread) { - RoInitialize(); + InitializeCom(); } return currentThread; @@ -151,16 +151,6 @@ namespace Internal.Runtime.Augments } /// <summary> - /// Ensures the Windows Runtime is initialized on the current thread. - /// </summary> - internal static void RoInitialize() - { -#if ENABLE_WINRT - Interop.WinRT.RoInitialize(); -#endif - } - - /// <summary> /// Returns true if the underlying OS thread has been created and started execution of managed code. /// </summary> private bool HasStarted() @@ -467,7 +457,7 @@ namespace Internal.Runtime.Augments { t_currentThread = thread; System.Threading.ManagedThreadId.SetForCurrentThread(thread._managedThreadId); - RoInitialize(); + thread.InitializeComOnNewThread(); } catch (OutOfMemoryException) { diff --git a/src/System.Private.CoreLib/src/Interop/Interop.WinRT.cs b/src/System.Private.CoreLib/src/Interop/Interop.WinRT.cs index 741ce4f21..0823dcffc 100644 --- a/src/System.Private.CoreLib/src/Interop/Interop.WinRT.cs +++ b/src/System.Private.CoreLib/src/Interop/Interop.WinRT.cs @@ -11,26 +11,13 @@ internal partial class Interop { private const string CORE_WINRT = "api-ms-win-core-winrt-l1-1-0.dll"; - private const int RPC_E_CHANGED_MODE = unchecked((int)0x80010106); + internal const uint RO_INIT_SINGLETHREADED = 0; + internal const uint RO_INIT_MULTITHREADED = 1; - private enum RO_INIT_TYPE : uint - { - RO_INIT_MULTITHREADED = 1 - } - - internal static void RoInitialize() - { - int hr = RoInitialize((uint)RO_INIT_TYPE.RO_INIT_MULTITHREADED); - - // RPC_E_CHANGED_MODE indicates this thread has been already initialized with a different - // concurrency model. That is fine; we just need to skip the RoUninitialize call on shutdown. - if ((hr < 0) && (hr != RPC_E_CHANGED_MODE)) - { - throw new OutOfMemoryException(); - } - } + [DllImport(CORE_WINRT, ExactSpelling = true)] + internal static extern int RoInitialize(uint initType); [DllImport(CORE_WINRT, ExactSpelling = true)] - private static extern int RoInitialize(uint initType); + internal static extern int RoUninitialize(); } } diff --git a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs index 261aad609..b54b15522 100644 --- a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs +++ b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs @@ -12,11 +12,6 @@ internal partial class Interop WaitObject0 = 0x0u, FailFastGenerateExceptionAddress = 0x1u, ExceptionNonContinuable = 0x1u, - CreateMutexInitialOwner = 0x1u, - CreateEventManualReset = 0x1u, - CreateEventInitialSet = 0x2u, - SemaphoreModifyState = 0x2u, - EventModifyState = 0x2u, DuplicateSameAccess = 0x2u, CreateSuspended = 0x4u, WaitAbandoned0 = 0x80u, @@ -25,7 +20,6 @@ internal partial class Interop WaitFailed = 0xFFFFFFFFu, } - // MCG doesn't currently support constants that are not uint. internal static IntPtr InvalidHandleValue => new IntPtr(-1); #pragma warning disable 649 diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.Windows.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.Windows.cs index 492247757..b9221327e 100644 --- a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.Windows.cs +++ b/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.Windows.cs @@ -4,6 +4,7 @@ using Microsoft.Win32.SafeHandles; using System; +using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -82,7 +83,7 @@ namespace Microsoft.Win32 { if (_hkey != null && IsDirty()) { - Interop.mincore.RegFlushKey(_hkey); + Interop.Advapi32.RegFlushKey(_hkey); } } @@ -93,7 +94,7 @@ namespace Microsoft.Win32 // By default, the new key will be writable. SafeRegistryHandle result = null; - int ret = Interop.mincore.RegCreateKeyEx(_hkey, + int ret = Interop.Advapi32.RegCreateKeyEx(_hkey, subkey, 0, null, @@ -185,7 +186,7 @@ namespace Microsoft.Win32 private RegistryKey InternalOpenSubKeyCore(string name, RegistryRights rights, bool throwOnPermissionFailure) { SafeRegistryHandle result = null; - int ret = Interop.mincore.RegOpenKeyEx(_hkey, name, 0, ((int)rights | (int)_regView), out result); + int ret = Interop.Advapi32.RegOpenKeyEx(_hkey, name, 0, ((int)rights | (int)_regView), out result); if (ret == 0 && !result.IsInvalid) { RegistryKey key = new RegistryKey(result, IsWritable((int)rights), false, _remoteKey, false, _regView); @@ -242,7 +243,7 @@ namespace Microsoft.Win32 // open the base key so that RegistryKey.Handle will return a valid handle SafeRegistryHandle result; - ret = Interop.mincore.RegOpenKeyEx(baseKey, + ret = Interop.Advapi32.RegOpenKeyEx(baseKey, null, 0, (int)GetRegistryKeyRights(IsWritable()) | (int)_regView, @@ -264,7 +265,7 @@ namespace Microsoft.Win32 { int subkeys = 0; int junk = 0; - int ret = Interop.mincore.RegQueryInfoKey(_hkey, + int ret = Interop.Advapi32.RegQueryInfoKey(_hkey, null, null, IntPtr.Zero, @@ -285,43 +286,52 @@ namespace Microsoft.Win32 return subkeys; } - private unsafe string[] InternalGetSubKeyNamesCore(int subkeys) + private string[] InternalGetSubKeyNamesCore(int subkeys) { - string[] names = new string[subkeys]; - char[] name = new char[MaxKeyLength + 1]; + var names = new List<string>(subkeys); + char[] name = ArrayPool<char>.Shared.Rent(MaxKeyLength + 1); - int namelen; - - fixed (char* namePtr = &name[0]) + try { - for (int i = 0; i < subkeys; i++) + 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) { - namelen = name.Length; // Don't remove this. The API's doesn't work if this is not properly initialized. - int ret = Interop.mincore.RegEnumKeyEx(_hkey, - i, - namePtr, - ref namelen, - null, - null, - null, - null); - if (ret != 0) + switch (result) { - Win32Error(ret, null); + case Interop.Errors.ERROR_SUCCESS: + names.Add(new string(name, 0, nameLength)); + nameLength = name.Length; + break; + default: + // Throw the error + Win32Error(result, null); + break; } - - names[i] = new string(namePtr); } } + finally + { + ArrayPool<char>.Shared.Return(name); + } - return names; + return names.ToArray(); } private int InternalValueCountCore() { int values = 0; int junk = 0; - int ret = Interop.mincore.RegQueryInfoKey(_hkey, + int ret = Interop.Advapi32.RegQueryInfoKey(_hkey, null, null, IntPtr.Zero, @@ -345,37 +355,79 @@ namespace Microsoft.Win32 /// <returns>All value names.</returns> private unsafe string[] GetValueNamesCore(int values) { - string[] names = new string[values]; - char[] name = new char[MaxValueLength + 1]; - int namelen; + var names = new List<string>(values); + + // 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); - fixed (char* namePtr = &name[0]) + try { - for (int i = 0; i < values; i++) + 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) { - namelen = name.Length; - - int ret = Interop.mincore.RegEnumValue(_hkey, - i, - namePtr, - ref namelen, - IntPtr.Zero, - null, - null, - null); - - if (ret != 0) + switch (result) { - // ignore ERROR_MORE_DATA if we're querying HKEY_PERFORMANCE_DATA - if (!(IsPerfDataKey() && ret == Interop.Errors.ERROR_MORE_DATA)) - Win32Error(ret, null); + // 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: + if (IsPerfDataKey()) + { + // Enumerating the values for Perf keys always returns + // ERROR_MORE_DATA, but has a valid name. Buffer does need + // to be big enough however. 8 characters is the largest + // known name. The size isn't returned, but the string is + // null terminated. + fixed (char* c = &name[0]) + { + names.Add(new string(c)); + } + } + else + { + 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; } - names[i] = new string(namePtr); + // Always set the name length back to the buffer size + nameLength = name.Length; } } + finally + { + if (name != null) + ArrayPool<char>.Shared.Return(name); + } - return names; + return names.ToArray(); } private object InternalGetValueCore(string name, object defaultValue, bool doNotExpand) @@ -384,7 +436,7 @@ namespace Microsoft.Win32 int type = 0; int datasize = 0; - int ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize); + int ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize); if (ret != 0) { @@ -395,7 +447,7 @@ namespace Microsoft.Win32 int r; byte[] blob = new byte[size]; - while (Interop.Errors.ERROR_MORE_DATA == (r = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, blob, ref sizeInput))) + while (Interop.Errors.ERROR_MORE_DATA == (r = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref sizeInput))) { if (size == int.MaxValue) { @@ -446,7 +498,7 @@ namespace Microsoft.Win32 case Interop.Advapi32.RegistryValues.REG_BINARY: { byte[] blob = new byte[datasize]; - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); + ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); data = blob; } break; @@ -460,7 +512,7 @@ namespace Microsoft.Win32 long blob = 0; Debug.Assert(datasize == 8, "datasize==8"); // Here, datasize must be 8 when calling this - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize); + ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize); data = blob; } @@ -475,7 +527,7 @@ namespace Microsoft.Win32 int blob = 0; Debug.Assert(datasize == 4, "datasize==4"); // Here, datasize must be four when calling this - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize); + ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize); data = blob; } @@ -497,7 +549,7 @@ namespace Microsoft.Win32 } char[] blob = new char[datasize / 2]; - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); + 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); @@ -527,7 +579,7 @@ namespace Microsoft.Win32 } char[] blob = new char[datasize / 2]; - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); + ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) { @@ -562,7 +614,7 @@ namespace Microsoft.Win32 } char[] blob = new char[datasize / 2]; - ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize); + 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) @@ -634,7 +686,7 @@ namespace Microsoft.Win32 { int type = 0; int datasize = 0; - int ret = Interop.mincore.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize); + int ret = Interop.Advapi32.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize); if (ret != 0) { Win32Error(ret, null); @@ -719,8 +771,8 @@ namespace Microsoft.Win32 private static bool IsWritable(int rights) { - return (rights & (Interop.mincore.RegistryOperations.KEY_SET_VALUE | - Interop.mincore.RegistryOperations.KEY_CREATE_SUB_KEY | + return (rights & (Interop.Advapi32.RegistryOperations.KEY_SET_VALUE | + Interop.Advapi32.RegistryOperations.KEY_CREATE_SUB_KEY | (int)RegistryRights.Delete | (int)RegistryRights.TakeOwnership | (int)RegistryRights.ChangePermissions)) != 0; diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.cs index 74d0ed362..ecf8376ed 100644 --- a/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.cs +++ b/src/System.Private.CoreLib/src/Microsoft/Win32/RegistryKey.cs @@ -562,16 +562,4 @@ namespace Microsoft.Win32 // Its not being used anywhere. public void SetValue(string name, object value, RegistryValueKind valueKind) { } } - - [Flags] -#if REGISTRY_ASSEMBLY - public -#else - internal -#endif - enum RegistryValueOptions - { - None = 0, - DoNotExpandEnvironmentNames = 1 - } } diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index c72d14531..5bacc1219 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -349,39 +349,7 @@ <ItemGroup Condition="'$(TargetsWindows)'=='true' and '$(EnableWinRT)'!='true'"> <Compile Include="Microsoft\Win32\RegistryKey.cs" /> <Compile Include="Microsoft\Win32\RegistryKey.Windows.cs" /> - <Compile Include="Microsoft\Win32\RegistryOptions.cs" /> <Compile Include="Microsoft\Win32\ThrowHelper.cs" /> - <Compile Include="System\Security\AccessControl\RegistryRights.cs" /> - <Compile Include="..\..\Common\src\Interop\Windows\advapi32\Interop.RegDeleteValue.cs"> - <Link>Interop\Windows\advapi32\Interop.RegDeleteValue.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\advapi32\Interop.RegSetValueEx.cs"> - <Link>Interop\Windows\advapi32\Interop.RegSetValueEx.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegistryOptions.cs"> - <Link>Interop\Windows\mincore\Interop.RegistryOptions.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegCreateKeyEx.cs"> - <Link>Interop\Windows\mincore\Interop.RegCreateKeyEx.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegEnumKeyEx.cs"> - <Link>Interop\Windows\mincore\Interop.RegEnumKeyEx.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegEnumValue.cs"> - <Link>Interop\Windows\mincore\Interop.RegEnumValue.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegFlushKey.cs"> - <Link>Interop\Windows\mincore\Interop.RegFlushKey.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegOpenKeyEx.cs"> - <Link>Interop\Windows\mincore\Interop.RegOpenKeyEx.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegQueryInfoKey.cs"> - <Link>Interop\Windows\mincore\Interop.RegQueryInfoKey.cs</Link> - </Compile> - <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.RegQueryValueEx.cs"> - <Link>Interop\Windows\mincore\Interop.RegQueryValueEx.cs</Link> - </Compile> <Compile Include="..\..\Common\src\Interop\Windows\Kernel32\Interop.ExitProcess.cs"> <Link>Interop\Windows\mincore\Interop.ExitProcess.cs</Link> </Compile> @@ -443,6 +411,12 @@ <Compile Include="..\..\Common\src\Interop\Windows\ole32\Interop.CoTaskMemAllocFree.cs"> <Link>Interop\Windows\ole32\Interop.CoTaskMemAllocFree.cs</Link> </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\ole32\Interop.CoInitializeEx.cs"> + <Link>Interop\Windows\ole32\Interop.CoInitializeEx.cs</Link> + </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\ole32\Interop.CoUninitialize.cs"> + <Link>Interop\Windows\ole32\Interop.CoUninitialize.cs</Link> + </Compile> <Compile Include="..\..\Common\src\Interop\Windows\ole32\Interop.CoGetApartmentType.cs"> <Link>Interop\Windows\ole32\Interop.CoGetApartmentType.cs</Link> </Compile> diff --git a/src/System.Private.CoreLib/src/System/PrimitivesRuntimeContracts.cs b/src/System.Private.CoreLib/src/System/PrimitivesRuntimeContracts.cs deleted file mode 100644 index b0ca615fe..000000000 --- a/src/System.Private.CoreLib/src/System/PrimitivesRuntimeContracts.cs +++ /dev/null @@ -1,409 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - -// This file contains the basic primitive type definitions (int etc) -// These types are well known to the compiler and the runtime and are basic interchange types that do not change - -// CONTRACT with Runtime -// Each of the data types has a data contract with the runtime. See the contract in the type definition -// - -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; - -namespace System -{ - // CONTRACT with Runtime - // Place holder type for type hierarchy, Compiler/Runtime requires this class - public abstract class ValueType - { - } - - // CONTRACT with Runtime, Compiler/Runtime requires this class - // Place holder type for type hierarchy - public abstract class Enum : ValueType - { - } - - /*============================================================ - ** - ** Class: Boolean - ** - ** - ** Purpose: The boolean class serves as a wrapper for the primitive - ** type boolean. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Boolean type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type bool - - public struct Boolean - { - private bool m_value; - } - - - /*============================================================ - ** - ** Class: Char - ** - ** - ** Purpose: This is the value class representing a Unicode character - ** - ** - ===========================================================*/ - - - - // CONTRACT with Runtime - // The Char type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type char - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Char - { - private char m_value; - } - - - /*============================================================ - ** - ** Class: SByte - ** - ** - ** Purpose: A representation of a 8 bit 2's complement integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The SByte type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type sbyte - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct SByte - { - private sbyte m_value; - } - - - /*============================================================ - ** - ** Class: Byte - ** - ** - ** Purpose: A representation of a 8 bit integer (byte) - ** - ** - ===========================================================*/ - - - // CONTRACT with Runtime - // The Byte type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type bool - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Byte - { - private byte m_value; - } - - - /*============================================================ - ** - ** Class: Int16 - ** - ** - ** Purpose: A representation of a 16 bit 2's complement integer. - ** - ** - ===========================================================*/ - - - // CONTRACT with Runtime - // The Int16 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type short - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Int16 - { - private short m_value; - } - - /*============================================================ - ** - ** Class: UInt16 - ** - ** - ** Purpose: A representation of a short (unsigned 16-bit) integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Uint16 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type ushort - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct UInt16 - { - private ushort m_value; - } - - /*============================================================ - ** - ** Class: Int32 - ** - ** - ** Purpose: A representation of a 32 bit 2's complement integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Int32 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type int - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Int32 - { - private int m_value; - } - - - /*============================================================ - ** - ** Class: UInt32 - ** - ** - ** Purpose: A representation of a 32 bit unsigned integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Uint32 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type uint - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct UInt32 - { - private uint m_value; - } - - - /*============================================================ - ** - ** Class: Int64 - ** - ** - ** Purpose: A representation of a 64 bit 2's complement integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Int64 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type long - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Int64 - { - private long m_value; - } - - - /*============================================================ - ** - ** Class: UInt64 - ** - ** - ** Purpose: A representation of a 64 bit unsigned integer. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The UInt64 type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type ulong - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct UInt64 - { - private ulong m_value; - } - - - /*============================================================ - ** - ** Class: Single - ** - ** - ** Purpose: A wrapper class for the primitive type float. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Single type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type float - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Single - { - private float m_value; - } - - - /*============================================================ - ** - ** Class: Double - ** - ** - ** Purpose: A representation of an IEEE double precision - ** floating point number. - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The Double type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type double - // This type is LayoutKind Sequential - - [StructLayout(LayoutKind.Sequential)] - public struct Double - { - private double m_value; - } - - - - /*============================================================ - ** - ** Class: IntPtr - ** - ** - ** Purpose: Platform independent integer - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The IntPtr type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type void * - - // This type implements == without overriding GetHashCode, disable compiler warning -#pragma warning disable 0659, 0661 - public struct IntPtr - { - unsafe private void* m_value; // The compiler treats void* closest to uint hence explicit casts are required to preserve int behavior - - public static readonly IntPtr Zero; - - public unsafe IntPtr(void* value) - { - m_value = value; - } - - public unsafe IntPtr(long value) - { -#if BIT64 - m_value = (void*)value; -#else - m_value = (void*)checked((int)value); -#endif - } - - public unsafe override bool Equals(Object obj) - { - if (obj is IntPtr) - { - return (m_value == ((IntPtr)obj).m_value); - } - return false; - } - - public unsafe bool Equals(IntPtr obj) - { - return (m_value == obj.m_value); - } - - public static unsafe explicit operator IntPtr(void* value) - { - return new IntPtr(value); - } - - public static unsafe explicit operator long (IntPtr value) - { -#if BIT64 - return (long)value.m_value; -#else - return (long)(int)value.m_value; -#endif - } - - public static unsafe bool operator ==(IntPtr value1, IntPtr value2) - { - return value1.m_value == value2.m_value; - } - - public static unsafe bool operator !=(IntPtr value1, IntPtr value2) - { - return value1.m_value != value2.m_value; - } - - public unsafe void* ToPointer() - { - return m_value; - } - } -#pragma warning restore 0659, 0661 - - - /*============================================================ - ** - ** Class: UIntPtr - ** - ** - ** Purpose: Platform independent integer - ** - ** - ===========================================================*/ - - // CONTRACT with Runtime - // The UIntPtr type is one of the primitives understood by the compilers and runtime - // Data Contract: Single field of type void * - - public struct UIntPtr - { - // Disable compile warning about unused m_value field -#pragma warning disable 0169 - unsafe private void* m_value; -#pragma warning restore 0169 - - public static readonly UIntPtr Zero; - } - - // Decimal class is not supported in RH. Only here to keep compiler happy - [TypeNeededIn(TypeNeededInOptions.SOURCE)] - internal struct Decimal - { - } -} - diff --git a/src/System.Private.CoreLib/src/System/Runtime/InitializeFinalizerThread.cs b/src/System.Private.CoreLib/src/System/Runtime/InitializeFinalizerThread.cs index 2b0e67bc8..cc52fda24 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InitializeFinalizerThread.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InitializeFinalizerThread.cs @@ -13,9 +13,9 @@ namespace System.Runtime [RuntimeExport("InitializeFinalizerThread")] public static void DoInitialize() { - // Make sure that the finalizer thread is RoInitialized before any objects are finalized. If this + // Make sure that the finalizer thread is CoInitialized before any objects are finalized. If this // fails, it will throw an exception and that will go unhandled, triggering a FailFast. - RuntimeThread.RoInitialize(); + RuntimeThread.InitializeCom(); } } } diff --git a/src/System.Private.CoreLib/src/System/Security/AccessControl/RegistryRights.cs b/src/System.Private.CoreLib/src/System/Security/AccessControl/RegistryRights.cs deleted file mode 100644 index 6359122ef..000000000 --- a/src/System.Private.CoreLib/src/System/Security/AccessControl/RegistryRights.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Win32; - -namespace System.Security.AccessControl -{ - // We derived this enum from the definitions of KEY_READ and such from - // winnt.h and from MSDN, plus some experimental validation with regedit. - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry_key_security_and_access_rights.asp - [Flags] -#if REGISTRY_ASSEMBLY - public -#else - internal -#endif - enum RegistryRights - { - // No None field - An ACE with the value 0 cannot grant nor deny. - QueryValues = Interop.mincore.RegistryOperations.KEY_QUERY_VALUE, // 0x0001 query the values of a registry key - SetValue = Interop.mincore.RegistryOperations.KEY_SET_VALUE, // 0x0002 create, delete, or set a registry value - CreateSubKey = Interop.mincore.RegistryOperations.KEY_CREATE_SUB_KEY, // 0x0004 required to create a subkey of a specific key - EnumerateSubKeys = Interop.mincore.RegistryOperations.KEY_ENUMERATE_SUB_KEYS, // 0x0008 required to enumerate sub keys of a key - Notify = Interop.mincore.RegistryOperations.KEY_NOTIFY, // 0x0010 needed to request change notifications - CreateLink = Interop.mincore.RegistryOperations.KEY_CREATE_LINK, // 0x0020 reserved for system use - /// - /// The Windows Kernel team agrees that it was a bad design to expose the WOW64_n options as permissions. - /// in the .NET Framework these options are exposed via the RegistryView enum - /// - /// Reg64 = Interop.mincore.RegistryOptions.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view - /// Reg32 = Interop.mincore.RegistryOptions.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view - ExecuteKey = ReadKey, - ReadKey = Interop.mincore.RegistryOperations.STANDARD_RIGHTS_READ | QueryValues | EnumerateSubKeys | Notify, - WriteKey = Interop.mincore.RegistryOperations.STANDARD_RIGHTS_WRITE | SetValue | CreateSubKey, - Delete = 0x10000, - ReadPermissions = 0x20000, - ChangePermissions = 0x40000, - TakeOwnership = 0x80000, - FullControl = 0xF003F | Interop.mincore.RegistryOperations.STANDARD_RIGHTS_READ | Interop.mincore.RegistryOperations.STANDARD_RIGHTS_WRITE - } -} diff --git a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs index e67b3b8c4..9548f2f08 100644 --- a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs +++ b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/RyuJitExecutionStrategy.cs @@ -22,6 +22,8 @@ namespace Internal.Runtime.JitSupport { public class RyuJitExecutionStrategy : MethodExecutionStrategy { + private const string NativeJitSupportLibrary = "*"; + private CorInfoImpl _corInfoImpl; private TypeSystemContext _context; private NodeFactory _nodeFactory; @@ -33,13 +35,13 @@ namespace Internal.Runtime.JitSupport return; } - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern IntPtr AllocJittedCode(UInt32 cbCode, UInt32 align, out IntPtr pCodeManager); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void SetEHInfoPtr(IntPtr pCodeManager, IntPtr pbCode, IntPtr ehInfo); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern unsafe IntPtr PublishRuntimeFunction( IntPtr pCodeManager, IntPtr pbCode, @@ -51,10 +53,10 @@ namespace Internal.Runtime.JitSupport byte[] pGCData, UInt32 cbGCData); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void UpdateRuntimeFunctionTable(IntPtr pCodeManager); - [DllImport("jitinterface")] + [DllImport(NativeJitSupportLibrary)] static extern void InitJitCodeManager(IntPtr mrtModule); public override IntPtr OnEntryPoint(MethodEntrypointPtr methodEntrypoint, IntPtr callerArgs) diff --git a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj new file mode 100644 index 000000000..637480fcb --- /dev/null +++ b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.Experimental.csproj @@ -0,0 +1,8 @@ +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> + <PropertyGroup> + <AssemblyName>System.Private.StackTraceMetadata.Experimental</AssemblyName> + <DynamicCodeSupport>true</DynamicCodeSupport> + </PropertyGroup> + + <Import Project="System.Private.StackTraceMetadata.csproj" /> +</Project> diff --git a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj index 799bc65e0..22c4b488c 100644 --- a/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj +++ b/src/System.Private.StackTraceMetadata/src/System.Private.StackTraceMetadata.csproj @@ -1,7 +1,7 @@ <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> - <AssemblyName>System.Private.StackTraceMetadata</AssemblyName> + <AssemblyName Condition="'$(AssemblyName)' == ''">System.Private.StackTraceMetadata</AssemblyName> <AssemblyVersion>4.0.0.0</AssemblyVersion> <OutputType>Library</OutputType> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> @@ -11,8 +11,10 @@ <ItemGroup Condition="'$(IsProjectNLibrary)' != 'true'"> <ProjectReference Include="..\..\System.Private.CoreLib\src\System.Private.CoreLib.csproj" /> <ProjectReference Include="..\..\System.Private.Reflection.Metadata\src\System.Private.Reflection.Metadata.csproj" /> - <ProjectReference Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj" /> - <ProjectReference Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj" /> + <ProjectReference Condition="'$(DynamicCodeSupport)' != 'true'" Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj" /> + <ProjectReference Condition="'$(DynamicCodeSupport)' != 'true'" Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj" /> + <ProjectReference Condition="'$(DynamicCodeSupport)' == 'true'" Include="..\..\System.Private.TypeLoader\src\System.Private.TypeLoader.Experimental.csproj" /> + <ProjectReference Condition="'$(DynamicCodeSupport)' == 'true'" Include="..\..\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.Experimental.csproj" /> </ItemGroup> <ItemGroup> |