[QUIC] Adopted msquic generated interop (#68288)
authorMarie Píchová <11718369+ManickaP@users.noreply.github.com>
Thu, 5 May 2022 10:32:25 +0000 (12:32 +0200)
committerGitHub <noreply@github.com>
Thu, 5 May 2022 10:32:25 +0000 (12:32 +0200)
* MsQuicApi adjusted

* QuicParamHelper adjusted

* MsQuicConfiguration adjusted

* Added MsQuicException

* MsQuicConnection adjusted

* MsQuicListener adjusted

* MsQuicStream adjusted

* It compiles!

* Some test fixes

* Fixed stream read event handling

* Re-enabled IPv6 tests

* latest greatest

* Update src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs

* MsQuic interop enum names

* 3rd Party notice, version check

* SafeHandleType

* Replaced AlpnHelpers with MsQuicBuffers generic QUIC_BUFFER* helper

* Sealed exception class

* Feedback MsQuicBuffers

* NativeMemory use

* Newest msquic interop

* Buffers feedback

* Remove MemoryHandle pooling

* Buffers feedback

* Logging feedback

38 files changed:
THIRD-PARTY-NOTICES.TXT
src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicBuffers.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicParameterHelpers.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicAlpnHelper.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicException.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicSafeHandle.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Linux.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.OSX.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Windows.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusHelper.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicTraceHelper.cs [deleted file]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConnectionHandle.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicListenerHandle.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicRegistrationHandle.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicStreamHandle.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_linux.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_macos.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_windows.cs [new file with mode: 0644]
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/NetEventSource.Quic.cs
src/libraries/System.Net.Quic/src/System/Net/Quic/QuicException.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/QuicConnectionTests.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs
src/libraries/System.Net.Quic/tests/FunctionalTests/QuicStreamTests.cs

index 2a94ef5..fc250aa 100644 (file)
@@ -1065,3 +1065,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 
+License notice for MsQuic
+--------------------------------------
+
+Copyright (c) Microsoft Corporation.
+Licensed under the MIT License.
+
+Available at
+https://github.com/microsoft/msquic/blob/main/LICENSE
\ No newline at end of file
index 0ecfed9..5a80b1d 100644 (file)
     <Compile Include="System\Net\Quic\Implementations\Mock\*.cs" />
     <Compile Include="System\Net\Quic\Implementations\MsQuic\*.cs" />
     <Compile Include="System\Net\Quic\Implementations\MsQuic\Internal\*.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicAlpnHelper.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicEnums.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicNativeMethods.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusHelper.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicTraceHelper.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicConfigurationHandle.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicConnectionHandle.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicListenerHandle.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicRegistrationHandle.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicStreamHandle.cs" />
-    <Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs">
-      <Link>Common\DisableRuntimeMarshalling.cs</Link>
-    </Compile>
+    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\*.cs" />
     <!-- System.Net common -->
+    <Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs" Link="Common\DisableRuntimeMarshalling.cs" />
     <Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
     <Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="Common\System\Net\ArrayBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="Common\System\Net\MultiArrayBuffer.cs" />
@@ -51,7 +39,6 @@
     <Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="Common\System\Net\StreamBuffer.cs" />
     <Compile Include="$(CommonPath)System\Net\SocketAddress.cs" Link="Common\System\Net\SocketAddress.cs" />
     <Compile Include="$(CommonPath)System\Net\IPAddressParserStatics.cs" Link="Common\System\Net\IPAddressParserStatics.cs" />
-    <!-- System.Net.Internals -->
     <Compile Include="$(CommonPath)System\Net\Internals\IPEndPointExtensions.cs" Link="Common\System\Net\Internals\IPEndPointExtensions.cs" />
   </ItemGroup>
   <!-- Unsupported platforms -->
@@ -74,7 +61,6 @@
     <Compile Include="$(CommonPath)Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs" Link="Common\Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Windows.cs" Link="Common\System\Net\Security\CertificateValidation.Windows.cs" />
     <Compile Include="$(CommonPath)System\Net\SocketAddressPal.Windows.cs" Link="Common\System\Net\SocketAddressPal.Windows.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.Windows.cs" />
   </ItemGroup>
   <!-- Unix (OSX + Linux) specific files -->
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'Linux' or '$(TargetPlatformIdentifier)' == 'OSX' or '$(TargetPlatformIdentifier)' == 'FreeBSD'">
   </ItemGroup>
   <!-- Linux specific files -->
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'Linux'">
-    <Compile Include="$(CommonPath)Interop\Linux\Interop.Libraries.cs" Link="Common\Interop\Linux\Interop.Libraries.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.Linux.cs" />
     <Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Unix.cs" Link="Common\System\Net\Security\CertificateValidation.Unix.cs" />
+    <Compile Include="$(CommonPath)Interop\Linux\Interop.Libraries.cs" Link="Common\Interop\Linux\Interop.Libraries.cs" />
   </ItemGroup>
   <!-- FreeBSD specific files -->
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'FreeBSD' ">
     <Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Unix.cs" Link="Common\System\Net\Security\CertificateValidation.Unix.cs" />
     <Compile Include="$(CommonPath)Interop\FreeBSD\Interop.Libraries.cs" Link="Common\Interop\FreeBSD\Interop.Libraries.cs" />
-    <!-- Assume similarity with OSX for now -->
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.OSX.cs" />
   </ItemGroup>
   <!-- OSX specific files -->
   <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'OSX'">
     <Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.OSX.cs" Link="Common\System\Net\Security\CertificateValidation.OSX.cs" />
     <Compile Include="$(CommonPath)Interop\OSX\Interop.Libraries.cs" Link="Common\Interop\OSX\Interop.Libraries.cs" />
-    <Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.OSX.cs" />
   </ItemGroup>
 
   <!-- Project references -->
-
   <ItemGroup>
     <PackageReference Include="System.Net.MsQuic.Transport"
                       Version="$(SystemNetMsQuicTransportVersion)"
index 9163794..e5092f6 100644 (file)
@@ -1,10 +1,6 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Net.Sockets;
-using System.Runtime.InteropServices;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
-
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
     internal static class MsQuicAddressHelpers
index 5f8fdd2..6eedee6 100644 (file)
@@ -3,21 +3,29 @@
 
 using System.Diagnostics.CodeAnalysis;
 using System.Runtime.InteropServices;
+using System.Text;
+using Microsoft.Quic;
+
+using static Microsoft.Quic.MsQuic;
 
 #if TARGET_WINDOWS
 using Microsoft.Win32;
 #endif
 
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
-
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
     internal sealed unsafe class MsQuicApi
     {
+        private static readonly byte[] s_appName = Encoding.ASCII.GetBytes("System.Net.Quic");
+
         private static readonly Version MinWindowsVersion = new Version(10, 0, 20145, 1000);
 
+        private static readonly Version MsQuicVersion = new Version(2, 0);
+
         public SafeMsQuicRegistrationHandle Registration { get; }
 
+        public QUIC_API_TABLE* ApiTable { get; }
+
         // This is workaround for a bug in ILTrimmer.
         // Without these DynamicDependency attributes, .ctor() will be removed from the safe handles.
         // Remove once fixed: https://github.com/mono/linker/issues/1660
@@ -26,89 +34,28 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
         [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicListenerHandle))]
         [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicConnectionHandle))]
         [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicStreamHandle))]
-        private MsQuicApi(NativeApi* vtable)
+        private MsQuicApi(QUIC_API_TABLE* apiTable)
         {
-            uint status;
-
-            SetParamDelegate =
-                new SetParamDelegate(new DelegateHelper(vtable->SetParam).SetParam);
-
-            GetParamDelegate =
-                new GetParamDelegate(new DelegateHelper(vtable->GetParam).GetParam);
-
-            SetCallbackHandlerDelegate =
-                new SetCallbackHandlerDelegate(new DelegateHelper(vtable->SetCallbackHandler).SetCallbackHandler);
-
-            RegistrationOpenDelegate =
-                new RegistrationOpenDelegate(new DelegateHelper(vtable->RegistrationOpen).RegistrationOpen);
-            RegistrationCloseDelegate =
-                Marshal.GetDelegateForFunctionPointer<RegistrationCloseDelegate>(
-                    vtable->RegistrationClose);
-
-            ConfigurationOpenDelegate =
-                new ConfigurationOpenDelegate(new DelegateHelper(vtable->ConfigurationOpen).ConfigurationOpen);
-            ConfigurationCloseDelegate =
-                Marshal.GetDelegateForFunctionPointer<ConfigurationCloseDelegate>(
-                    vtable->ConfigurationClose);
-            ConfigurationLoadCredentialDelegate =
-                new ConfigurationLoadCredentialDelegate(new DelegateHelper(vtable->ConfigurationLoadCredential).ConfigurationLoadCredential);
-
-            ListenerOpenDelegate =
-                new ListenerOpenDelegate(new DelegateHelper(vtable->ListenerOpen).ListenerOpen);
-            ListenerCloseDelegate =
-                Marshal.GetDelegateForFunctionPointer<ListenerCloseDelegate>(
-                    vtable->ListenerClose);
-            ListenerStartDelegate =
-                new ListenerStartDelegate(new DelegateHelper(vtable->ListenerStart).ListenerStart);
-            ListenerStopDelegate =
-                new ListenerStopDelegate(new DelegateHelper(vtable->ListenerStop).ListenerStop);
-
-            ConnectionOpenDelegate =
-                new ConnectionOpenDelegate(new DelegateHelper(vtable->ConnectionOpen).ConnectionOpen);
-            ConnectionCloseDelegate =
-                Marshal.GetDelegateForFunctionPointer<ConnectionCloseDelegate>(
-                    vtable->ConnectionClose);
-            ConnectionSetConfigurationDelegate =
-                new ConnectionSetConfigurationDelegate(new DelegateHelper(vtable->ConnectionSetConfiguration).ConnectionSetConfiguration);
-            ConnectionShutdownDelegate =
-                new ConnectionShutdownDelegate(new DelegateHelper(vtable->ConnectionShutdown).ConnectionShutdown);
-            ConnectionStartDelegate =
-                new ConnectionStartDelegate(new DelegateHelper(vtable->ConnectionStart).ConnectionStart);
-
-            StreamOpenDelegate =
-                new StreamOpenDelegate(new DelegateHelper(vtable->StreamOpen).StreamOpen);
-            StreamCloseDelegate =
-                Marshal.GetDelegateForFunctionPointer<StreamCloseDelegate>(
-                    vtable->StreamClose);
-            StreamStartDelegate =
-                new StreamStartDelegate(new DelegateHelper(vtable->StreamStart).StreamStart);
-            StreamShutdownDelegate =
-                new StreamShutdownDelegate(new DelegateHelper(vtable->StreamShutdown).StreamShutdown);
-            StreamSendDelegate =
-                new StreamSendDelegate(new DelegateHelper(vtable->StreamSend).StreamSend);
-            StreamReceiveCompleteDelegate =
-                new StreamReceiveCompleteDelegate(new DelegateHelper(vtable->StreamReceiveComplete).StreamReceiveComplete);
-            StreamReceiveSetEnabledDelegate =
-                new StreamReceiveSetEnabledDelegate(new DelegateHelper(vtable->StreamReceiveSetEnabled).StreamReceiveSetEnabled);
-
-            var cfg = new RegistrationConfig
+            ApiTable = apiTable;
+
+            fixed (byte* pAppName = s_appName)
             {
-                AppName = ".NET",
-                ExecutionProfile = QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY
-            };
+                var cfg = new QUIC_REGISTRATION_CONFIG {
+                    AppName = (sbyte*)pAppName,
+                    ExecutionProfile = QUIC_EXECUTION_PROFILE.LOW_LATENCY
+                };
 
-            status = RegistrationOpenDelegate(ref cfg, out SafeMsQuicRegistrationHandle handle);
-            QuicExceptionHelpers.ThrowIfFailed(status, "RegistrationOpen failed.");
+                QUIC_HANDLE* handle;
+                ThrowIfFailure(ApiTable->RegistrationOpen(&cfg, &handle), "RegistrationOpen failed");
 
-            Registration = handle;
+                Registration = new SafeMsQuicRegistrationHandle(handle);
+            }
         }
 
         internal static MsQuicApi Api { get; } = null!;
 
         internal static bool IsQuicSupported { get; }
 
-        private const int MsQuicVersion = 2;
-
         internal static bool Tls13MayBeDisabled { get; }
 
         static MsQuicApi()
@@ -129,21 +76,36 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
             }
 
             IntPtr msQuicHandle;
-            if (NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle) ||
+            if (NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion.Major}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle) ||
                 NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle))
             {
                 try
                 {
                     if (NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpenVersion", out IntPtr msQuicOpenVersionAddress))
                     {
-                        NativeApi* vtable;
-                        delegate* unmanaged[Cdecl]<uint, NativeApi**, uint> msQuicOpenVersion =
-                            (delegate* unmanaged[Cdecl]<uint, NativeApi**, uint>)msQuicOpenVersionAddress;
-                        uint status = msQuicOpenVersion(MsQuicVersion, &vtable);
-                        if (MsQuicStatusHelper.SuccessfulStatusCode(status))
+                        QUIC_API_TABLE* apiTable;
+                        delegate* unmanaged[Cdecl]<uint, QUIC_API_TABLE**, int> msQuicOpenVersion = (delegate* unmanaged[Cdecl]<uint, QUIC_API_TABLE**, int>)msQuicOpenVersionAddress;
+                        if (StatusSucceeded(msQuicOpenVersion((uint)MsQuicVersion.Major, &apiTable)))
                         {
-                            IsQuicSupported = true;
-                            Api = new MsQuicApi(vtable);
+                            int arraySize = 4;
+                            uint* libVersion = stackalloc uint[arraySize];
+                            uint size = (uint)arraySize * sizeof(uint);
+                            if (StatusSucceeded(apiTable->GetParam(null, QUIC_PARAM_GLOBAL_LIBRARY_VERSION, &size, libVersion)))
+                            {
+                                var version = new Version((int)libVersion[0], (int)libVersion[1], (int)libVersion[2], (int)libVersion[3]);
+                                if (version >= MsQuicVersion)
+                                {
+                                    Api = new MsQuicApi(apiTable);
+                                    IsQuicSupported = true;
+                                }
+                                else
+                                {
+                                    if (NetEventSource.Log.IsEnabled())
+                                    {
+                                        NetEventSource.Info(null, $"Incompatible MsQuic library version '{version}', expecting '{MsQuicVersion}'");
+                                    }
+                                }
+                            }
                         }
                     }
                 }
@@ -182,38 +144,5 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
 #endif
             return false;
         }
-
-        // TODO: Consider updating all of these delegates to instead use function pointers.
-        internal RegistrationOpenDelegate RegistrationOpenDelegate { get; }
-        internal RegistrationCloseDelegate RegistrationCloseDelegate { get; }
-
-        internal ConfigurationOpenDelegate ConfigurationOpenDelegate { get; }
-        internal ConfigurationCloseDelegate ConfigurationCloseDelegate { get; }
-        internal ConfigurationLoadCredentialDelegate ConfigurationLoadCredentialDelegate { get; }
-
-        internal ListenerOpenDelegate ListenerOpenDelegate { get; }
-        internal ListenerCloseDelegate ListenerCloseDelegate { get; }
-        internal ListenerStartDelegate ListenerStartDelegate { get; }
-        internal ListenerStopDelegate ListenerStopDelegate { get; }
-
-        // TODO: missing SendResumptionTicket
-        internal ConnectionOpenDelegate ConnectionOpenDelegate { get; }
-        internal ConnectionCloseDelegate ConnectionCloseDelegate { get; }
-        internal ConnectionShutdownDelegate ConnectionShutdownDelegate { get; }
-        internal ConnectionStartDelegate ConnectionStartDelegate { get; }
-        internal ConnectionSetConfigurationDelegate ConnectionSetConfigurationDelegate { get; }
-
-        internal StreamOpenDelegate StreamOpenDelegate { get; }
-        internal StreamCloseDelegate StreamCloseDelegate { get; }
-        internal StreamStartDelegate StreamStartDelegate { get; }
-        internal StreamShutdownDelegate StreamShutdownDelegate { get; }
-        internal StreamSendDelegate StreamSendDelegate { get; }
-        internal StreamReceiveCompleteDelegate StreamReceiveCompleteDelegate { get; }
-        internal StreamReceiveSetEnabledDelegate StreamReceiveSetEnabledDelegate { get; }
-
-        internal SetCallbackHandlerDelegate SetCallbackHandlerDelegate { get; }
-
-        internal SetParamDelegate SetParamDelegate { get; }
-        internal GetParamDelegate GetParamDelegate { get; }
     }
 }
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicBuffers.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicBuffers.cs
new file mode 100644 (file)
index 0000000..e98e977
--- /dev/null
@@ -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.
+
+using System.Buffers;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Microsoft.Quic;
+
+namespace System.Net.Quic.Implementations.MsQuic.Internal;
+
+/// <summary>
+/// Helper class to convert managed data into QUIC_BUFFER* consumable by MsQuic.
+/// It also allows reuse with repeated Reset/Initialize calls, e.g. new, Initialize, (use), Reset, Initialize, (use), Reset, Initialize, (use), Dispose.
+/// Note that since this is struct and there's no finalizer, Dispose must be always called to release the unmanaged memory allocated by this struct.
+/// </summary>
+internal unsafe struct MsQuicBuffers : IDisposable
+{
+    // Handles to pinned memory blocks from the user.
+    private MemoryHandle[] _handles;
+    // Native memory block which holds the pinned memory pointers from _handles and can be passed to MsQuic as QUIC_BUFFER*.
+    private QUIC_BUFFER* _buffers;
+    // Number of QUIC_BUFFER instance currently allocated in _buffers, so that we can reuse the memory instead of reallocating.
+    private int _count;
+
+    public MsQuicBuffers()
+    {
+        _handles = Array.Empty<MemoryHandle>();
+        _buffers = null;
+        _count = 0;
+    }
+
+    public QUIC_BUFFER* Buffers => _buffers;
+    public int Count => _count;
+
+    private void FreeNativeMemory()
+    {
+        QUIC_BUFFER* buffers = _buffers;
+        _buffers = null;
+        NativeMemory.Free(buffers);
+    }
+
+    /// <summary>
+    /// The method initializes QUIC_BUFFER* with data from inputs, converted via toBuffer.
+    /// Note that the struct either needs to be freshly created via new or previously cleaned up with Reset.
+    /// </summary>
+    /// <param name="inputs">Inputs to get their byte array, pin them and pepare them to be passed to MsQuic as QUIC_BUFFER*.</param>
+    /// <param name="toBuffer">Method extracting byte array from the inputs, e.g. applicationProtocol.Protocol.</param>
+    /// <typeparam name="T">The type of the inputs.</typeparam>
+    public void Initialize<T>(IList<T> inputs, Func<T, ReadOnlyMemory<byte>> toBuffer)
+    {
+        if (_handles.Length < inputs.Count)
+        {
+            _handles = new MemoryHandle[inputs.Count];
+        }
+        if (_count < inputs.Count)
+        {
+            FreeNativeMemory();
+            _buffers = (QUIC_BUFFER*)NativeMemory.Alloc((nuint)sizeof(QUIC_BUFFER), (nuint)inputs.Count);
+        }
+
+        _count = inputs.Count;
+
+        for (int i = 0; i < inputs.Count; ++i)
+        {
+            ReadOnlyMemory<byte> buffer = toBuffer(inputs[i]);
+            MemoryHandle handle = buffer.Pin();
+
+            _handles[i] = handle;
+            _buffers[i].Buffer = (byte*)handle.Pointer;
+            _buffers[i].Length = (uint)buffer.Length;
+        }
+    }
+
+    /// <summary>
+    /// Unpins the managed memory and allows reuse of this struct.
+    /// </summary>
+    public void Reset()
+    {
+        for (int i = 0; i < _count; ++i)
+        {
+            _handles[i].Dispose();
+        }
+    }
+
+    /// <summary>
+    /// Apart from unpinning the managed memory, it returns the shared buffer,
+    /// but most importantly it releases the unmanaged memory.
+    /// </summary>
+    public void Dispose()
+    {
+        Reset();
+        FreeNativeMemory();
+    }
+}
index 7fef8a8..784d895 100644 (file)
@@ -4,13 +4,13 @@
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Net.Sockets;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
+using static Microsoft.Quic.MsQuic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
     internal static class MsQuicParameterHelpers
     {
-        internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, SafeHandle nativeObject, uint param)
+        internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param)
         {
             // MsQuic always uses storage size as if IPv6 was used
             uint valueLen = (uint)Internals.SocketAddress.IPv6AddressSize;
@@ -18,17 +18,19 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
 
             fixed (byte* paddress = &MemoryMarshal.GetReference(address))
             {
-                uint status = api.GetParamDelegate(nativeObject, param, ref valueLen, paddress);
-                QuicExceptionHelpers.ThrowIfFailed(status, "GetIPEndPointParam failed.");
+                ThrowIfFailure(api.ApiTable->GetParam(
+                    nativeObject.QuicHandle,
+                    param,
+                    &valueLen,
+                    paddress), "GetIPEndPointParam failed.");
             }
 
             address = address.Slice(0, (int)valueLen);
 
-            return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(address), address)
-                .GetIPEndPoint();
+            return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(address), address).GetIPEndPoint();
         }
 
-        internal static unsafe void SetIPEndPointParam(MsQuicApi api, SafeHandle nativeObject, uint param, IPEndPoint value)
+        internal static unsafe void SetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param, IPEndPoint value)
         {
             Internals.SocketAddress socketAddress = IPEndPointExtensions.Serialize(value);
 
@@ -39,48 +41,60 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
 
             fixed (byte* paddress = &MemoryMarshal.GetReference(address))
             {
-                QuicExceptionHelpers.ThrowIfFailed(
-                    api.SetParamDelegate(nativeObject, param, (uint)address.Length, paddress),
-                    "Could not set IPEndPoint");
+                ThrowIfFailure(api.ApiTable->SetParam(
+                    nativeObject.QuicHandle,
+                    param,
+                    (uint)address.Length,
+                    paddress), "Could not set IPEndPoint");
             }
         }
 
-        internal static unsafe ushort GetUShortParam(MsQuicApi api, SafeHandle nativeObject, uint param)
+        internal static unsafe ushort GetUShortParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param)
         {
             ushort value;
             uint valueLen = (uint)sizeof(ushort);
 
-            uint status = api.GetParamDelegate(nativeObject, param, ref valueLen, (byte*)&value);
-            QuicExceptionHelpers.ThrowIfFailed(status, "GetUShortParam failed.");
+            ThrowIfFailure(api.ApiTable->GetParam(
+                nativeObject.QuicHandle,
+                param,
+                &valueLen,
+                (byte*)&value), "GetUShortParam failed");
             Debug.Assert(valueLen == sizeof(ushort));
 
             return value;
         }
 
-        internal static unsafe void SetUShortParam(MsQuicApi api, SafeHandle nativeObject, uint param, ushort value)
+        internal static unsafe void SetUShortParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param, ushort value)
         {
-            QuicExceptionHelpers.ThrowIfFailed(
-                api.SetParamDelegate(nativeObject, param, sizeof(ushort), (byte*)&value),
-                "Could not set ushort.");
+            ThrowIfFailure(api.ApiTable->SetParam(
+                nativeObject.QuicHandle,
+                param,
+                sizeof(ushort),
+                (byte*)&value), "Could not set ushort");
         }
 
-        internal static unsafe ulong GetULongParam(MsQuicApi api, SafeHandle nativeObject, uint param)
+        internal static unsafe ulong GetULongParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param)
         {
             ulong value;
             uint valueLen = (uint)sizeof(ulong);
 
-            uint status = api.GetParamDelegate(nativeObject, param, ref valueLen, (byte*)&value);
-            QuicExceptionHelpers.ThrowIfFailed(status, "GetULongParam failed.");
+            ThrowIfFailure(api.ApiTable->GetParam(
+                nativeObject.QuicHandle,
+                param,
+                &valueLen,
+                (byte*)&value), "GetULongParam failed");
             Debug.Assert(valueLen == sizeof(ulong));
 
             return value;
         }
 
-        internal static unsafe void SetULongParam(MsQuicApi api, SafeHandle nativeObject, uint param, ulong value)
+        internal static unsafe void SetULongParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param, ulong value)
         {
-            QuicExceptionHelpers.ThrowIfFailed(
-                api.SetParamDelegate(nativeObject, param, sizeof(ulong), (byte*)&value),
-                "Could not set ulong.");
+            ThrowIfFailure(api.ApiTable->SetParam(
+                nativeObject.QuicHandle,
+                param,
+                sizeof(ulong),
+                (byte*)&value), "Could not set ulong");
         }
     }
 }
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs
deleted file mode 100644 (file)
index 680069b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Net.Sockets;
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static class QuicExceptionHelpers
-    {
-        internal static void ThrowIfFailed(uint status, string? message = null, Exception? innerException = null)
-        {
-            if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
-            {
-                throw CreateExceptionForHResult(status, message, innerException);
-            }
-        }
-
-        internal static Exception CreateExceptionForHResult(uint status, string? message = null, Exception? innerException = null)
-        {
-            return new QuicException($"{message} Error Code: {MsQuicStatusCodes.GetError(status)}", innerException, MapMsQuicStatusToHResult(status));
-        }
-
-        internal static int MapMsQuicStatusToHResult(uint status)
-        {
-            switch (status)
-            {
-                case MsQuicStatusCodes.ConnectionRefused:
-                    return (int)SocketError.ConnectionRefused;  // 0x8007274D - WSAECONNREFUSED
-                case MsQuicStatusCodes.ConnectionTimeout:
-                    return (int)SocketError.TimedOut;           // 0x8007274C - WSAETIMEDOUT
-                case MsQuicStatusCodes.HostUnreachable:
-                    return (int)SocketError.HostUnreachable;
-                default:
-                    return 0;
-            }
-        }
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicAlpnHelper.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicAlpnHelper.cs
deleted file mode 100644 (file)
index 916cfc4..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Net.Security;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static class MsQuicAlpnHelper
-    {
-        public static unsafe void Prepare(List<SslApplicationProtocol> alpnProtocols, [NotNull] out MemoryHandle[]? handles, [NotNull] out QuicBuffer[]? buffers)
-        {
-            handles = ArrayPool<MemoryHandle>.Shared.Rent(alpnProtocols.Count);
-            buffers = ArrayPool<QuicBuffer>.Shared.Rent(alpnProtocols.Count);
-
-            try
-            {
-                for (int i = 0; i < alpnProtocols.Count; ++i)
-                {
-                    ReadOnlyMemory<byte> alpnProtocol = alpnProtocols[i].Protocol;
-                    MemoryHandle h = alpnProtocol.Pin();
-
-                    handles[i] = h;
-                    buffers[i].Buffer = (byte*)h.Pointer;
-                    buffers[i].Length = (uint)alpnProtocol.Length;
-                }
-            }
-            catch
-            {
-                Return(ref handles, ref buffers);
-                throw;
-            }
-        }
-
-        public static void Return(ref MemoryHandle[]? handles, ref QuicBuffer[]? buffers)
-        {
-            if (handles is MemoryHandle[] notNullHandles)
-            {
-                foreach (MemoryHandle h in notNullHandles)
-                {
-                    h.Dispose();
-                }
-
-                handles = null;
-                ArrayPool<MemoryHandle>.Shared.Return(notNullHandles);
-            }
-
-            if (buffers is QuicBuffer[] notNullBuffers)
-            {
-                buffers = null;
-                ArrayPool<QuicBuffer>.Shared.Return(notNullBuffers);
-            }
-        }
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs
deleted file mode 100644 (file)
index 8745dd5..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal enum QUIC_EXECUTION_PROFILE : uint
-    {
-        QUIC_EXECUTION_PROFILE_LOW_LATENCY, // Default
-        QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT,
-        QUIC_EXECUTION_PROFILE_TYPE_SCAVENGER,
-        QUIC_EXECUTION_PROFILE_TYPE_REAL_TIME,
-    }
-
-    internal enum QUIC_CREDENTIAL_TYPE : uint
-    {
-        NONE,
-        HASH,
-        HASH_STORE,
-        CONTEXT,
-        FILE,
-        FILE_PROTECTED,
-        PKCS12,
-    }
-
-    [Flags]
-    internal enum QUIC_CREDENTIAL_FLAGS : uint
-    {
-        NONE = 0x00000000,
-        CLIENT = 0x00000001, // Lack of client flag indicates server.
-        LOAD_ASYNCHRONOUS = 0x00000002,
-        NO_CERTIFICATE_VALIDATION = 0x00000004,
-        ENABLE_OCSP = 0x00000008, // Schannel only currently.
-        INDICATE_CERTIFICATE_RECEIVED = 0x00000010,
-        DEFER_CERTIFICATE_VALIDATION = 0x00000020, // Schannel only currently.
-        REQUIRE_CLIENT_AUTHENTICATION = 0x00000040, // Schannel only currently.
-        USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080,
-        SET_ALLOWED_CIPHER_SUITES = 0x00002000,
-        USE_PORTABLE_CERTIFICATES = 0x00004000,
-    }
-
-    [Flags]
-    internal enum QUIC_ALLOWED_CIPHER_SUITE_FLAGS : uint
-    {
-        NONE = 0x0,
-        AES_128_GCM_SHA256 = 0x1,
-        AES_256_GCM_SHA384 = 0x2,
-        CHACHA20_POLY1305_SHA256 = 0x4,
-    }
-
-    internal enum QUIC_CERTIFICATE_HASH_STORE_FLAGS
-    {
-        QUIC_CERTIFICATE_HASH_STORE_FLAG_NONE = 0x0000,
-        QUIC_CERTIFICATE_HASH_STORE_FLAG_MACHINE_STORE = 0x0001,
-    }
-
-    [Flags]
-    internal enum QUIC_CONNECTION_SHUTDOWN_FLAGS : uint
-    {
-        NONE = 0x0000,
-        SILENT = 0x0001, // Don't send the close frame over the network.
-    }
-
-    internal enum QUIC_SERVER_RESUMPTION_LEVEL : uint
-    {
-        NO_RESUME,
-        RESUME_ONLY,
-        RESUME_AND_ZERORTT,
-    }
-
-    [Flags]
-    internal enum QUIC_STREAM_OPEN_FLAGS : uint
-    {
-        NONE = 0x0000,
-        UNIDIRECTIONAL = 0x0001, // Indicates the stream is unidirectional.
-        ZERO_RTT = 0x0002, // The stream was opened via a 0-RTT packet.
-    }
-
-    [Flags]
-    internal enum QUIC_STREAM_START_FLAGS : uint
-    {
-        NONE = 0x0000,
-        IMMEDIATE = 0x0001, // Immediately informs peer that stream is open.
-        FAIL_BLOCKED = 0x0002, // Only opens the stream if flow control allows.
-        SHUTDOWN_ON_FAIL = 0x0004, // Shutdown the stream immediately after start failure.
-        INDICATE_PEER_ACCEPT = 0x0008, // PEER_ACCEPTED event to be delivered if the stream isn't initially accepted.
-    }
-
-    [Flags]
-    internal enum QUIC_STREAM_SHUTDOWN_FLAGS : uint
-    {
-        NONE = 0x0000,
-        GRACEFUL = 0x0001, // Cleanly closes the send path.
-        ABORT_SEND = 0x0002, // Abruptly closes the send path.
-        ABORT_RECEIVE = 0x0004, // Abruptly closes the receive path.
-        ABORT = 0x0006, // Abruptly closes both send and receive paths.
-        IMMEDIATE = 0x0008, // Immediately sends completion events to app.
-    }
-
-    [Flags]
-    internal enum QUIC_RECEIVE_FLAGS : uint
-    {
-        NONE = 0x0000,
-        ZERO_RTT = 0x0001, // Data was encrypted with 0-RTT key.
-        FIN = 0x0002, // FIN was included with this data.
-    }
-
-    [Flags]
-    internal enum QUIC_SEND_FLAGS : uint
-    {
-        NONE = 0x0000,
-        ALLOW_0_RTT = 0x0001, // Allows the use of encrypting with 0-RTT key.
-        START = 0x0002, // Asynchronously starts the stream with the sent data.
-        FIN = 0x0004, // Indicates the request is the one last sent on the stream.
-        DGRAM_PRIORITY = 0x0008, // Indicates the datagram is higher priority than others.
-        DELAY_SEND = 0x0010, // Indicates the send should be delayed because more will be queued soon.
-    }
-
-    internal enum QUIC_PARAM_PREFIX : uint
-    {
-        GLOBAL = 0x01000000,
-        REGISTRATION = 0x02000000,
-        CONFIGURATION = 0x03000000,
-        LISTENER = 0x04000000,
-        CONNECTION = 0x05000000,
-        TLS = 0x06000000,
-        TLS_SCHANNEL = 0x07000000,
-        STREAM = 0x08000000,
-    }
-
-    internal enum QUIC_PARAM_GLOBAL : uint
-    {
-        RETRY_MEMORY_PERCENT = 0 | QUIC_PARAM_PREFIX.GLOBAL, // uint16_t
-        SUPPORTED_VERSIONS = 1 | QUIC_PARAM_PREFIX.GLOBAL, // uint32_t[] - network byte order
-        LOAD_BALANCING_MODE = 2 | QUIC_PARAM_PREFIX.GLOBAL, // uint16_t - QUIC_LOAD_BALANCING_MODE
-        PERF_COUNTERS = 3 | QUIC_PARAM_PREFIX.GLOBAL, // uint64_t[] - Array size is QUIC_PERF_COUNTER_MAX
-        SETTINGS = 4 | QUIC_PARAM_PREFIX.GLOBAL, // QUIC_SETTINGS
-    }
-
-    internal enum QUIC_PARAM_REGISTRATION : uint
-    {
-        CID_PREFIX = 0 | QUIC_PARAM_PREFIX.REGISTRATION, // uint8_t[]
-    }
-
-    internal enum QUIC_PARAM_LISTENER : uint
-    {
-        LOCAL_ADDRESS = 0 | QUIC_PARAM_PREFIX.LISTENER, // QUIC_ADDR
-        STATS = 1 | QUIC_PARAM_PREFIX.LISTENER, // QUIC_LISTENER_STATISTICS
-    }
-
-    internal enum QUIC_PARAM_CONN : uint
-    {
-        QUIC_VERSION = 0 | QUIC_PARAM_PREFIX.CONNECTION, // uint32_t
-        LOCAL_ADDRESS = 1 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_ADDR
-        REMOTE_ADDRESS = 2 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_ADDR
-        IDEAL_PROCESSOR = 3 | QUIC_PARAM_PREFIX.CONNECTION, // uint16_t
-        SETTINGS = 4 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_SETTINGS
-        STATISTICS = 5 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_STATISTICS
-        STATISTICS_PLAT = 6 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_STATISTICS
-        SHARE_UDP_BINDING = 7 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t (BOOLEAN)
-        LOCAL_BIDI_STREAM_COUNT = 8 | QUIC_PARAM_PREFIX.CONNECTION, // uint16_t
-        LOCAL_UNIDI_STREAM_COUNT = 9 | QUIC_PARAM_PREFIX.CONNECTION, // uint16_t
-        MAX_STREAM_IDS = 10 | QUIC_PARAM_PREFIX.CONNECTION, // uint64_t[4]
-        CLOSE_REASON_PHRASE = 11 | QUIC_PARAM_PREFIX.CONNECTION, // char[]
-        STREAM_SCHEDULING_SCHEME = 12 | QUIC_PARAM_PREFIX.CONNECTION, // QUIC_STREAM_SCHEDULING_SCHEME
-        DATAGRAM_RECEIVE_ENABLED = 13 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t (BOOLEAN)
-        DATAGRAM_SEND_ENABLED = 14 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t (BOOLEAN)
-        DISABLE_1RTT_ENCRYPTION = 15 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t (BOOLEAN)
-        RESUMPTION_TICKET = 16 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t[]
-        PEER_CERTIFICATE_VALID = 17 | QUIC_PARAM_PREFIX.CONNECTION, // uint8_t (BOOLEAN)
-    }
-
-    internal enum QUIC_PARAM_STREAM : uint
-    {
-        ID = 0 | QUIC_PARAM_PREFIX.STREAM, // QUIC_UINT62
-        ZERRTT_LENGTH = 1 | QUIC_PARAM_PREFIX.STREAM, // uint64_t
-        IDEAL_SEND_BUFFER_SIZE = 2 | QUIC_PARAM_PREFIX.STREAM, // uint64_t - bytes
-    }
-
-    internal enum QUIC_LISTENER_EVENT : uint
-    {
-        NEW_CONNECTION = 0,
-        STOP_COMPLETE = 1,
-    }
-
-    internal enum QUIC_CONNECTION_EVENT_TYPE : uint
-    {
-        CONNECTED = 0,
-        SHUTDOWN_INITIATED_BY_TRANSPORT = 1, // The transport started the shutdown process.
-        SHUTDOWN_INITIATED_BY_PEER = 2, // The peer application started the shutdown process.
-        SHUTDOWN_COMPLETE = 3, // Ready for the handle to be closed.
-        LOCAL_ADDRESS_CHANGED = 4,
-        PEER_ADDRESS_CHANGED = 5,
-        PEER_STREAM_STARTED = 6,
-        STREAMS_AVAILABLE = 7,
-        PEER_NEEDS_STREAMS = 8,
-        IDEAL_PROCESSOR_CHANGED = 9,
-        DATAGRAM_STATE_CHANGED = 10,
-        DATAGRAM_RECEIVED = 11,
-        DATAGRAM_SEND_STATE_CHANGED = 12,
-        RESUMED = 13, // Server-only; provides resumption data, if any.
-        RESUMPTION_TICKET_RECEIVED = 14, // Client-only; provides ticket to persist, if any.
-        PEER_CERTIFICATE_RECEIVED = 15, // Only with QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED set.
-    }
-
-    internal enum QUIC_STREAM_EVENT_TYPE : uint
-    {
-        START_COMPLETE = 0,
-        RECEIVE = 1,
-        SEND_COMPLETE = 2,
-        PEER_SEND_SHUTDOWN = 3,
-        PEER_SEND_ABORTED = 4,
-        PEER_RECEIVE_ABORTED = 5,
-        SEND_SHUTDOWN_COMPLETE = 6,
-        SHUTDOWN_COMPLETE = 7,
-        IDEAL_SEND_BUFFER_SIZE = 8,
-        PEER_ACCEPTED = 9
-    }
-
-#if SOCKADDR_HAS_LENGTH
-    internal enum QUIC_ADDRESS_FAMILY : byte
-#else
-    internal enum QUIC_ADDRESS_FAMILY : ushort
-#endif
-    {
-        UNSPEC = 0,
-        INET = 2,
-        INET6 = 23,
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicException.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicException.cs
new file mode 100644 (file)
index 0000000..2dd3f11
--- /dev/null
@@ -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.
+
+using System;
+using System.Net.Quic;
+using System.Net.Sockets;
+using static Microsoft.Quic.MsQuic;
+
+namespace Microsoft.Quic
+{
+    internal sealed class MsQuicException : QuicException
+    {
+        public int Status { get; }
+
+        public MsQuicException(int status, string? message = null, Exception? innerException = null)
+            : base($"{(message ?? nameof(MsQuicException))}: {GetErrorCodeForStatus(status)}", innerException, MapMsQuicStatusToHResult(status))
+        {
+            Status = status;
+        }
+
+        public static string GetErrorCodeForStatus(int status)
+        {
+            if (status == MsQuic.QUIC_STATUS_SUCCESS) return "QUIC_STATUS_SUCCESS";
+            else if (status == MsQuic.QUIC_STATUS_PENDING) return "QUIC_STATUS_PENDING";
+            else if (status == MsQuic.QUIC_STATUS_CONTINUE) return "QUIC_STATUS_CONTINUE";
+            else if (status == MsQuic.QUIC_STATUS_OUT_OF_MEMORY) return "QUIC_STATUS_OUT_OF_MEMORY";
+            else if (status == MsQuic.QUIC_STATUS_INVALID_PARAMETER) return "QUIC_STATUS_INVALID_PARAMETER";
+            else if (status == MsQuic.QUIC_STATUS_INVALID_STATE) return "QUIC_STATUS_INVALID_STATE";
+            else if (status == MsQuic.QUIC_STATUS_NOT_SUPPORTED) return "QUIC_STATUS_NOT_SUPPORTED";
+            else if (status == MsQuic.QUIC_STATUS_NOT_FOUND) return "QUIC_STATUS_NOT_FOUND";
+            else if (status == MsQuic.QUIC_STATUS_BUFFER_TOO_SMALL) return "QUIC_STATUS_BUFFER_TOO_SMALL";
+            else if (status == MsQuic.QUIC_STATUS_HANDSHAKE_FAILURE) return "QUIC_STATUS_HANDSHAKE_FAILURE";
+            else if (status == MsQuic.QUIC_STATUS_ABORTED) return "QUIC_STATUS_ABORTED";
+            else if (status == MsQuic.QUIC_STATUS_ADDRESS_IN_USE) return "QUIC_STATUS_ADDRESS_IN_USE";
+            else if (status == MsQuic.QUIC_STATUS_CONNECTION_TIMEOUT) return "QUIC_STATUS_CONNECTION_TIMEOUT";
+            else if (status == MsQuic.QUIC_STATUS_CONNECTION_IDLE) return "QUIC_STATUS_CONNECTION_IDLE";
+            else if (status == MsQuic.QUIC_STATUS_UNREACHABLE) return "QUIC_STATUS_UNREACHABLE";
+            else if (status == MsQuic.QUIC_STATUS_INTERNAL_ERROR) return "QUIC_STATUS_INTERNAL_ERROR";
+            else if (status == MsQuic.QUIC_STATUS_CONNECTION_REFUSED) return "QUIC_STATUS_CONNECTION_REFUSED";
+            else if (status == MsQuic.QUIC_STATUS_PROTOCOL_ERROR) return "QUIC_STATUS_PROTOCOL_ERROR";
+            else if (status == MsQuic.QUIC_STATUS_VER_NEG_ERROR) return "QUIC_STATUS_VER_NEG_ERROR";
+            else if (status == MsQuic.QUIC_STATUS_TLS_ERROR) return "QUIC_STATUS_TLS_ERROR";
+            else if (status == MsQuic.QUIC_STATUS_USER_CANCELED) return "QUIC_STATUS_USER_CANCELED";
+            else if (status == MsQuic.QUIC_STATUS_ALPN_NEG_FAILURE) return "QUIC_STATUS_ALPN_NEG_FAILURE";
+            else if (status == MsQuic.QUIC_STATUS_STREAM_LIMIT_REACHED) return "QUIC_STATUS_STREAM_LIMIT_REACHED";
+            else if (status == MsQuic.QUIC_STATUS_CLOSE_NOTIFY) return "QUIC_STATUS_CLOSE_NOTIFY";
+            else if (status == MsQuic.QUIC_STATUS_BAD_CERTIFICATE) return "QUIC_STATUS_BAD_CERTIFICATE";
+            else if (status == MsQuic.QUIC_STATUS_UNSUPPORTED_CERTIFICATE) return "QUIC_STATUS_UNSUPPORTED_CERTIFICATE";
+            else if (status == MsQuic.QUIC_STATUS_REVOKED_CERTIFICATE) return "QUIC_STATUS_REVOKED_CERTIFICATE";
+            else if (status == MsQuic.QUIC_STATUS_EXPIRED_CERTIFICATE) return "QUIC_STATUS_EXPIRED_CERTIFICATE";
+            else if (status == MsQuic.QUIC_STATUS_UNKNOWN_CERTIFICATE) return "QUIC_STATUS_UNKNOWN_CERTIFICATE";
+            else if (status == MsQuic.QUIC_STATUS_CERT_EXPIRED) return "QUIC_STATUS_CERT_EXPIRED";
+            else if (status == MsQuic.QUIC_STATUS_CERT_UNTRUSTED_ROOT) return "QUIC_STATUS_CERT_UNTRUSTED_ROOT";
+            else return $"Unknown status '{status}'";
+        }
+
+        public static int MapMsQuicStatusToHResult(int status)
+        {
+            if (status == QUIC_STATUS_CONNECTION_REFUSED) return (int)SocketError.ConnectionRefused;  // 0x8007274D - WSAECONNREFUSED
+            else if (status == QUIC_STATUS_CONNECTION_TIMEOUT) return (int)SocketError.TimedOut;      // 0x8007274C - WSAETIMEDOUT
+            else if (status == QUIC_STATUS_UNREACHABLE) return (int)SocketError.HostUnreachable;
+            else return 0;
+        }
+    }
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
deleted file mode 100644 (file)
index 165a4b2..0000000
+++ /dev/null
@@ -1,1438 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.Marshalling;
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    /// <summary>
-    /// Contains all native delegates and structs that are used with MsQuic.
-    /// </summary>
-    internal static unsafe partial class MsQuicNativeMethods
-    {
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct NativeApi
-        {
-            internal IntPtr SetContext;
-            internal IntPtr GetContext;
-            internal IntPtr SetCallbackHandler;
-
-            internal IntPtr SetParam;
-            internal IntPtr GetParam;
-
-            internal IntPtr RegistrationOpen;
-            internal IntPtr RegistrationClose;
-            internal IntPtr RegistrationShutdown;
-
-            internal IntPtr ConfigurationOpen;
-            internal IntPtr ConfigurationClose;
-            internal IntPtr ConfigurationLoadCredential;
-
-            internal IntPtr ListenerOpen;
-            internal IntPtr ListenerClose;
-            internal IntPtr ListenerStart;
-            internal IntPtr ListenerStop;
-
-            internal IntPtr ConnectionOpen;
-            internal IntPtr ConnectionClose;
-            internal IntPtr ConnectionShutdown;
-            internal IntPtr ConnectionStart;
-            internal IntPtr ConnectionSetConfiguration;
-            internal IntPtr ConnectionSendResumptionTicket;
-
-            internal IntPtr StreamOpen;
-            internal IntPtr StreamClose;
-            internal IntPtr StreamStart;
-            internal IntPtr StreamShutdown;
-            internal IntPtr StreamSend;
-            internal IntPtr StreamReceiveComplete;
-            internal IntPtr StreamReceiveSetEnabled;
-
-            internal IntPtr DatagramSend;
-        }
-
-        internal delegate uint SetContextDelegate(
-            SafeHandle handle,
-            IntPtr context);
-
-        internal delegate IntPtr GetContextDelegate(
-            SafeHandle handle);
-
-        internal delegate void SetCallbackHandlerDelegate(
-            SafeHandle handle,
-            Delegate del,
-            IntPtr context);
-
-        internal delegate uint SetParamDelegate(
-            SafeHandle handle,
-            uint param,
-            uint bufferLength,
-            byte* buffer);
-
-        internal delegate uint GetParamDelegate(
-            SafeHandle handle,
-            uint param,
-            ref uint bufferLength,
-            byte* buffer);
-
-        internal delegate uint RegistrationOpenDelegate(
-            ref RegistrationConfig config,
-            out SafeMsQuicRegistrationHandle registrationContext);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RegistrationCloseDelegate(
-            IntPtr registrationContext);
-
-        [NativeMarshalling(typeof(Native))]
-        internal struct RegistrationConfig
-        {
-            internal string AppName;
-            internal QUIC_EXECUTION_PROFILE ExecutionProfile;
-
-            [CustomTypeMarshaller(typeof(RegistrationConfig), Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
-            [StructLayout(LayoutKind.Sequential)]
-            public struct Native
-            {
-                private IntPtr AppName;
-                private QUIC_EXECUTION_PROFILE ExecutionProfile;
-
-                public Native(RegistrationConfig managed)
-                {
-                    AppName = Marshal.StringToCoTaskMemUTF8(managed.AppName);
-                    ExecutionProfile = managed.ExecutionProfile;
-                }
-
-                public RegistrationConfig ToManaged()
-                {
-                    return new RegistrationConfig()
-                    {
-                        AppName = Marshal.PtrToStringUTF8(AppName)!,
-                        ExecutionProfile = ExecutionProfile
-                    };
-                }
-
-                public void FreeNative()
-                {
-                    Marshal.FreeCoTaskMem(AppName);
-                }
-            }
-        }
-
-        internal delegate uint ConfigurationOpenDelegate(
-            SafeMsQuicRegistrationHandle registrationContext,
-            QuicBuffer* alpnBuffers,
-            uint alpnBufferCount,
-            ref QuicSettings settings,
-            uint settingsSize,
-            IntPtr context,
-            out SafeMsQuicConfigurationHandle configuration);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ConfigurationCloseDelegate(
-            IntPtr configuration);
-
-        internal delegate uint ConfigurationLoadCredentialDelegate(
-            SafeMsQuicConfigurationHandle configuration,
-            ref CredentialConfig credConfig);
-
-        internal struct AnyDelegateMarshaller
-        {
-            private readonly Delegate _managed;
-
-            public AnyDelegateMarshaller(Delegate managed)
-            {
-                _managed = managed;
-                Value = Marshal.GetFunctionPointerForDelegate(_managed);
-            }
-
-            public IntPtr Value { get; }
-
-            public void FreeNative()
-            {
-                GC.KeepAlive(_managed);
-            }
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct QuicSettings
-        {
-            internal QuicSettingsIsSetFlags IsSetFlags;
-            internal ulong MaxBytesPerKey;
-            internal ulong HandshakeIdleTimeoutMs;
-            internal ulong IdleTimeoutMs;
-            internal ulong MtuDiscoverySearchCompleteTimeoutUs;
-            internal uint TlsClientMaxSendBuffer;
-            internal uint TlsServerMaxSendBuffer;
-            internal uint StreamRecvWindowDefault;
-            internal uint StreamRecvBufferDefault;
-            internal uint ConnFlowControlWindow;
-            internal uint MaxWorkerQueueDelayUs;
-            internal uint MaxStatelessOperations;
-            internal uint InitialWindowPackets;
-            internal uint SendIdleTimeoutMs;
-            internal uint InitialRttMs;
-            internal uint MaxAckDelayMs;
-            internal uint DisconnectTimeoutMs;
-            internal uint KeepAliveIntervalMs;
-            internal ushort CongestionControlAlgorithm; // QUIC_CONGESTION_CONTROL_ALGORITHM
-            internal ushort PeerBidiStreamCount;
-            internal ushort PeerUnidiStreamCount;
-            internal ushort MaxBindingStatelessOperations;
-            internal ushort StatelessOperationExpirationMs;
-            internal ushort MinimumMtu;
-            internal ushort MaximumMtu;
-            internal QuicSettingsEnabledFlagsFlags EnabledFlags;
-            internal byte MaxOperationsPerDrain;
-            internal byte MtuDiscoveryMissingProbeCount;
-        }
-
-        [Flags]
-        internal enum QuicSettingsIsSetFlags : ulong
-        {
-            MaxBytesPerKey = 1UL << 0,
-            HandshakeIdleTimeoutMs = 1UL << 1,
-            IdleTimeoutMs = 1UL << 2,
-            MtuDiscoverySearchCompleteTimeoutUs = 1UL << 3,
-            TlsClientMaxSendBuffer = 1UL << 4,
-            TlsServerMaxSendBuffer = 1UL << 5,
-            StreamRecvWindowDefault = 1UL << 6,
-            StreamRecvBufferDefault = 1UL << 7,
-            ConnFlowControlWindow = 1UL << 8,
-            MaxWorkerQueueDelayUs = 1UL << 9,
-            MaxStatelessOperations = 1UL << 10,
-            InitialWindowPackets = 1UL << 11,
-            SendIdleTimeoutMs = 1UL << 12,
-            InitialRttMs = 1UL << 13,
-            MaxAckDelayMs = 1UL << 14,
-            DisconnectTimeoutMs = 1UL << 15,
-            KeepAliveIntervalMs = 1UL << 16,
-            CongestionControlAlgorithm = 1UL << 17,
-            PeerBidiStreamCount = 1UL << 18,
-            PeerUnidiStreamCount = 1UL << 19,
-            MaxBindingStatelessOperations = 1UL << 20,
-            StatelessOperationExpirationMs = 1UL << 21,
-            MinimumMtu = 1UL << 22,
-            MaximumMtu = 1UL << 23,
-            SendBufferingEnabled = 1UL << 24,
-            PacingEnabled = 1UL << 25,
-            MigrationEnabled = 1UL << 26,
-            DatagramReceiveEnabled = 1UL << 27,
-            ServerResumptionLevel = 1UL << 28,
-            MaxOperationsPerDrain = 1UL << 29,
-            MtuDiscoveryMissingProbeCount = 1UL << 31,
-        }
-
-        [Flags]
-        internal enum QuicSettingsEnabledFlagsFlags : byte
-        {
-            SendBufferingEnabled = 1 << 0,
-            PacingEnabled = 1 << 1,
-            MigrationEnabled = 1 << 2,
-            DatagramReceiveEnabled = 1 << 3,
-            // Contains values of QUIC_SERVER_RESUMPTION_LEVEL
-            ServerResumptionLevel = 1 << 4 | 1 << 5,
-            VersionNegotiationExtEnabled = 1 << 6,
-        }
-
-        [NativeMarshalling(typeof(Native))]
-        internal struct CredentialConfig
-        {
-            internal QUIC_CREDENTIAL_TYPE Type;
-            internal QUIC_CREDENTIAL_FLAGS Flags;
-            // CredentialConfigCertificateUnion*
-            internal IntPtr Certificate;
-
-            internal string Principal;
-            internal IntPtr Reserved; // Currently unused
-            // TODO: define delegate for AsyncHandler and make proper use of it.
-            internal IntPtr AsyncHandler;
-            internal QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites;
-
-            [CustomTypeMarshaller(typeof(CredentialConfig), Features = CustomTypeMarshallerFeatures.UnmanagedResources)]
-            [StructLayout(LayoutKind.Sequential)]
-            public struct Native
-            {
-                internal QUIC_CREDENTIAL_TYPE Type;
-                internal QUIC_CREDENTIAL_FLAGS Flags;
-                // CredentialConfigCertificateUnion*
-                internal IntPtr Certificate;
-                internal IntPtr Principal;
-                internal IntPtr Reserved;
-                internal IntPtr AsyncHandler;
-                internal QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites;
-
-                public Native(CredentialConfig managed)
-                {
-                    Type = managed.Type;
-                    Flags = managed.Flags;
-                    Certificate = managed.Certificate;
-                    Principal = Marshal.StringToCoTaskMemUTF8(managed.Principal);
-                    Reserved = managed.Reserved;
-                    AsyncHandler = managed.AsyncHandler;
-                    AllowedCipherSuites = managed.AllowedCipherSuites;
-                }
-
-                public CredentialConfig ToManaged()
-                {
-                    return new CredentialConfig
-                    {
-                        Type = Type,
-                        Flags = Flags,
-                        Certificate = Certificate,
-                        Principal = Marshal.PtrToStringUTF8(Principal)!,
-                        Reserved = Reserved,
-                        AsyncHandler = AsyncHandler,
-                        AllowedCipherSuites = AllowedCipherSuites
-                    };
-                }
-
-                public void FreeNative()
-                {
-                    Marshal.FreeCoTaskMem(Principal);
-                }
-            }
-        }
-
-        [StructLayout(LayoutKind.Explicit)]
-        internal struct CredentialConfigCertificateUnion
-        {
-            [FieldOffset(0)]
-            internal CredentialConfigCertificateHash CertificateHash;
-
-            [FieldOffset(0)]
-            internal CredentialConfigCertificateHashStore CertificateHashStore;
-
-            [FieldOffset(0)]
-            internal IntPtr CertificateContext;
-
-            [FieldOffset(0)]
-            internal CredentialConfigCertificateFile CertificateFile;
-
-            [FieldOffset(0)]
-            internal CredentialConfigCertificateFileProtected CertificateFileProtected;
-
-            [FieldOffset(0)]
-            internal CredentialConfigCertificatePkcs12 CertificatePkcs12;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct CredentialConfigCertificateHash
-        {
-            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
-            internal byte[] ShaHash;
-        }
-
-        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
-        internal struct CredentialConfigCertificateHashStore
-        {
-            internal QUIC_CERTIFICATE_HASH_STORE_FLAGS Flags;
-
-            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
-            internal byte[] ShaHash;
-
-            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
-            internal char[] StoreName;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct CredentialConfigCertificateFile
-        {
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            internal string PrivateKeyFile;
-
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            internal string CertificateFile;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct CredentialConfigCertificateFileProtected
-        {
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            internal string PrivateKeyFile;
-
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            internal string CertificateFile;
-
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            internal string PrivateKeyPassword;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct CredentialConfigCertificatePkcs12
-        {
-            internal IntPtr Asn1Blob;
-
-            internal uint Asn1BlobLength;
-
-            internal IntPtr PrivateKeyPassword;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ListenerEvent
-        {
-            internal QUIC_LISTENER_EVENT Type;
-            internal ListenerEventDataUnion Data;
-        }
-
-        [StructLayout(LayoutKind.Explicit)]
-        internal struct ListenerEventDataUnion
-        {
-            [FieldOffset(0)]
-            internal ListenerEventDataNewConnection NewConnection;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ListenerEventDataNewConnection
-        {
-            internal NewConnectionInfo* Info;
-            internal IntPtr Connection;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct NewConnectionInfo
-        {
-            internal uint QuicVersion;
-            // QUIC_ADDR
-            internal IntPtr LocalAddress;
-            // QUIC_ADDR
-            internal IntPtr RemoteAddress;
-            internal uint CryptoBufferLength;
-            internal ushort ClientAlpnListLength;
-            internal ushort ServerNameLength;
-            internal byte NegotiatedAlpnLength;
-            // byte[]
-            internal IntPtr CryptoBuffer;
-            // byte[]
-            internal IntPtr ClientAlpnList;
-            // byte[]
-            internal IntPtr NegotiatedAlpn;
-            // string
-            internal IntPtr ServerName;
-        }
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate uint ListenerCallbackDelegate(
-            IntPtr listener,
-            IntPtr context,
-            ListenerEvent* evt);
-
-        internal delegate uint ListenerOpenDelegate(
-           SafeMsQuicRegistrationHandle registration,
-           ListenerCallbackDelegate handler,
-           IntPtr context,
-           out SafeMsQuicListenerHandle listener);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ListenerCloseDelegate(
-            IntPtr listener);
-
-        internal delegate uint ListenerStartDelegate(
-            SafeMsQuicListenerHandle listener,
-            QuicBuffer* alpnBuffers,
-            uint alpnBufferCount,
-            byte* localAddress);
-
-        internal delegate void ListenerStopDelegate(
-            SafeMsQuicListenerHandle listener);
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataConnected
-        {
-            internal byte SessionResumed;
-            internal byte NegotiatedAlpnLength;
-            // byte[]
-            internal IntPtr NegotiatedAlpn;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataShutdownInitiatedByTransport
-        {
-            internal uint Status;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataShutdownInitiatedByPeer
-        {
-            internal long ErrorCode;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataShutdownComplete
-        {
-            // The flags have fixed sized exactly 3 bits
-            internal ConnectionEventDataShutdownCompleteFlags Flags;
-        }
-
-        [Flags]
-        internal enum ConnectionEventDataShutdownCompleteFlags : byte
-        {
-            HandshakeCompleted = 1 << 0,
-            PeerAcknowledgedShutdown = 1 << 1,
-            AppCloseInProgress = 1 << 2,
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataLocalAddressChanged
-        {
-            // QUIC_ADDR
-            internal IntPtr Address;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataPeerAddressChanged
-        {
-            // QUIC_ADDR
-            internal IntPtr Address;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataPeerStreamStarted
-        {
-            internal IntPtr Stream;
-            internal QUIC_STREAM_OPEN_FLAGS Flags;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventDataStreamsAvailable
-        {
-            internal ushort BiDirectionalCount;
-            internal ushort UniDirectionalCount;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEventPeerCertificateReceived
-        {
-            internal IntPtr PlatformCertificateHandle;
-            internal uint DeferredErrorFlags;
-            internal uint DeferredStatus;
-            internal IntPtr PlatformCertificateChainHandle;
-        }
-
-        [StructLayout(LayoutKind.Explicit)]
-        internal struct ConnectionEventDataUnion
-        {
-            [FieldOffset(0)]
-            internal ConnectionEventDataConnected Connected;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataShutdownInitiatedByTransport ShutdownInitiatedByTransport;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataShutdownInitiatedByPeer ShutdownInitiatedByPeer;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataShutdownComplete ShutdownComplete;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataLocalAddressChanged LocalAddressChanged;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataPeerAddressChanged PeerAddressChanged;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataPeerStreamStarted PeerStreamStarted;
-
-            [FieldOffset(0)]
-            internal ConnectionEventDataStreamsAvailable StreamsAvailable;
-
-            [FieldOffset(0)]
-            internal ConnectionEventPeerCertificateReceived PeerCertificateReceived;
-
-            // TODO: missing IDEAL_PROCESSOR_CHANGED, ...,  (6 total)
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct ConnectionEvent
-        {
-            internal QUIC_CONNECTION_EVENT_TYPE Type;
-            internal ConnectionEventDataUnion Data;
-        }
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate uint ConnectionCallbackDelegate(
-            IntPtr connection,
-            IntPtr context,
-            ConnectionEvent* connectionEvent);
-
-        // TODO: order is Open, Close, Shutdown, Start, SetConfiguration, SendResumptionTicket
-        internal delegate uint ConnectionOpenDelegate(
-            SafeMsQuicRegistrationHandle registration,
-            ConnectionCallbackDelegate handler,
-            IntPtr context,
-            out SafeMsQuicConnectionHandle connection);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ConnectionCloseDelegate(
-            IntPtr connection);
-
-        internal delegate uint ConnectionSetConfigurationDelegate(
-            SafeMsQuicConnectionHandle connection,
-            SafeMsQuicConfigurationHandle configuration);
-
-        internal delegate uint ConnectionStartDelegate(
-            SafeMsQuicConnectionHandle connection,
-            SafeMsQuicConfigurationHandle configuration,
-            QUIC_ADDRESS_FAMILY family,
-            [MarshalAs(UnmanagedType.LPUTF8Str)]
-            string serverName,
-            ushort serverPort);
-
-        internal delegate void ConnectionShutdownDelegate(
-            SafeMsQuicConnectionHandle connection,
-            QUIC_CONNECTION_SHUTDOWN_FLAGS flags,
-            long errorCode);
-
-        // TODO: missing SendResumptionTicket
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataStartComplete
-        {
-            internal uint Status;
-            internal ulong Id;
-            internal byte PeerAccepted;
-        };
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataReceive
-        {
-            internal ulong AbsoluteOffset;
-            internal ulong TotalBufferLength;
-            internal QuicBuffer* Buffers;
-            internal uint BufferCount;
-            internal QUIC_RECEIVE_FLAGS Flags;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataSendComplete
-        {
-            internal byte Canceled;
-            internal IntPtr ClientContext;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataPeerSendAborted
-        {
-            internal long ErrorCode;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataPeerReceiveAborted
-        {
-            internal long ErrorCode;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataSendShutdownComplete
-        {
-            internal byte Graceful;
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEventDataShutdownComplete
-        {
-            internal byte ConnectionShutdown;
-        }
-
-        [StructLayout(LayoutKind.Explicit)]
-        internal struct StreamEventDataUnion
-        {
-            [FieldOffset(0)]
-            internal StreamEventDataStartComplete StartComplete;
-
-            [FieldOffset(0)]
-            internal StreamEventDataReceive Receive;
-
-            [FieldOffset(0)]
-            internal StreamEventDataSendComplete SendComplete;
-
-            [FieldOffset(0)]
-            internal StreamEventDataPeerSendAborted PeerSendAborted;
-
-            [FieldOffset(0)]
-            internal StreamEventDataPeerReceiveAborted PeerReceiveAborted;
-
-            [FieldOffset(0)]
-            internal StreamEventDataSendShutdownComplete SendShutdownComplete;
-
-            [FieldOffset(0)]
-            internal StreamEventDataShutdownComplete ShutdownComplete;
-
-            // TODO: missing IDEAL_SEND_BUFFER_SIZE
-        }
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct StreamEvent
-        {
-            internal QUIC_STREAM_EVENT_TYPE Type;
-            internal StreamEventDataUnion Data;
-        }
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate uint StreamCallbackDelegate(
-            IntPtr stream,
-            IntPtr context,
-            StreamEvent* streamEvent);
-
-        internal delegate uint StreamOpenDelegate(
-            SafeMsQuicConnectionHandle connection,
-            QUIC_STREAM_OPEN_FLAGS flags,
-            StreamCallbackDelegate handler,
-            IntPtr context,
-            out SafeMsQuicStreamHandle stream);
-
-        internal delegate uint StreamStartDelegate(
-            SafeMsQuicStreamHandle stream,
-            QUIC_STREAM_START_FLAGS flags);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void StreamCloseDelegate(
-            IntPtr stream);
-
-        internal delegate uint StreamShutdownDelegate(
-            SafeMsQuicStreamHandle stream,
-            QUIC_STREAM_SHUTDOWN_FLAGS flags,
-            long errorCode);
-
-        internal delegate uint StreamSendDelegate(
-            SafeMsQuicStreamHandle stream,
-            QuicBuffer* buffers,
-            uint bufferCount,
-            QUIC_SEND_FLAGS flags,
-            IntPtr clientSendContext);
-
-        internal delegate void StreamReceiveCompleteDelegate(
-            SafeMsQuicStreamHandle stream,
-            ulong bufferLength);
-
-        internal delegate uint StreamReceiveSetEnabledDelegate(
-            SafeMsQuicStreamHandle stream,
-            bool enabled);
-
-        [StructLayout(LayoutKind.Sequential)]
-        internal struct QuicBuffer
-        {
-            internal uint Length;
-            internal byte* Buffer;
-        }
-
-        // TODO: DatagramSend missing
-
-        internal struct DelegateHelper
-        {
-            private IntPtr _functionPointer;
-
-            public DelegateHelper(IntPtr functionPointer)
-            {
-                _functionPointer = functionPointer;
-            }
-            internal uint SetContext(SafeHandle handle, IntPtr context)
-            {
-                IntPtr __handle_gen_native;
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool handle__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    handle.DangerousAddRef(ref handle__addRefd);
-                    __handle_gen_native = handle.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, uint>)_functionPointer)(__handle_gen_native, context);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (handle__addRefd)
-                        handle.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal IntPtr GetContext(SafeHandle handle)
-            {
-                IntPtr __handle_gen_native;
-                IntPtr __retVal;
-                //
-                // Setup
-                //
-                bool handle__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    handle.DangerousAddRef(ref handle__addRefd);
-                    __handle_gen_native = handle.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr>)_functionPointer)(__handle_gen_native);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (handle__addRefd)
-                        handle.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal void SetCallbackHandler(SafeHandle handle, Delegate del, IntPtr context)
-            {
-                //
-                // Setup
-                //
-                bool handle__addRefd = false;
-                AnyDelegateMarshaller __del_gen_native__marshaller = default;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    handle.DangerousAddRef(ref handle__addRefd);
-                    IntPtr __handle_gen_native = handle.DangerousGetHandle();
-                    __del_gen_native__marshaller = new AnyDelegateMarshaller(del);
-                    IntPtr __del_gen_native = __del_gen_native__marshaller.Value;
-                    ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void>)_functionPointer)(__handle_gen_native, __del_gen_native, context);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (handle__addRefd)
-                        handle.DangerousRelease();
-                    __del_gen_native__marshaller.FreeNative();
-                }
-            }
-            internal uint SetParam(SafeHandle handle, uint param, uint bufferLength, byte* buffer)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool handle__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    handle.DangerousAddRef(ref handle__addRefd);
-                    IntPtr __handle_gen_native = handle.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, uint, uint, byte*, uint>)_functionPointer)(__handle_gen_native, param, bufferLength, buffer);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (handle__addRefd)
-                        handle.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint GetParam(SafeHandle handle, uint param, ref uint bufferLength, byte* buffer)
-            {
-                IntPtr __handle_gen_native = default;
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool handle__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    handle.DangerousAddRef(ref handle__addRefd);
-                    __handle_gen_native = handle.DangerousGetHandle();
-                    fixed (uint* __bufferLength_gen_native = &bufferLength)
-                    {
-                        __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, uint, uint*, byte*, uint>)_functionPointer)(__handle_gen_native, param, __bufferLength_gen_native, buffer);
-                    }
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (handle__addRefd)
-                        handle.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint RegistrationOpen(ref RegistrationConfig config, out SafeMsQuicRegistrationHandle registrationContext)
-            {
-                RegistrationConfig.Native __config_gen_native = default;
-                registrationContext = default!;
-                IntPtr __registrationContext_gen_native = default;
-                uint __retVal;
-                bool __invokeSucceeded = default;
-                //
-                // Setup
-                //
-                SafeMsQuicRegistrationHandle registrationContext__newHandle = new SafeMsQuicRegistrationHandle();
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    __config_gen_native = new RegistrationConfig.Native(config);
-                    __retVal = ((delegate* unmanaged[Cdecl]<RegistrationConfig.Native*, IntPtr*, uint>)_functionPointer)(&__config_gen_native, &__registrationContext_gen_native);
-                    __invokeSucceeded = true;
-                    //
-                    // Unmarshal
-                    //
-                    config = __config_gen_native.ToManaged();
-                }
-                finally
-                {
-                    if (__invokeSucceeded)
-                    {
-                        //
-                        // GuaranteedUnmarshal
-                        //
-                        Marshal.InitHandle(registrationContext__newHandle, __registrationContext_gen_native);
-                        registrationContext = registrationContext__newHandle;
-                    }
-
-                    //
-                    // Cleanup
-                    //
-                    __config_gen_native.FreeNative();
-                }
-
-                return __retVal;
-            }
-            internal uint ConfigurationOpen(SafeMsQuicRegistrationHandle registrationContext, QuicBuffer* alpnBuffers, uint alpnBufferCount, ref QuicSettings settings, uint settingsSize, IntPtr context, out SafeMsQuicConfigurationHandle configuration)
-            {
-                IntPtr __registrationContext_gen_native = default;
-                configuration = default!;
-                IntPtr __configuration_gen_native = default;
-                uint __retVal;
-                bool __invokeSucceeded = default;
-                //
-                // Setup
-                //
-                bool registrationContext__addRefd = false;
-                SafeMsQuicConfigurationHandle configuration__newHandle = new SafeMsQuicConfigurationHandle();
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    registrationContext.DangerousAddRef(ref registrationContext__addRefd);
-                    __registrationContext_gen_native = registrationContext.DangerousGetHandle();
-                    fixed (QuicSettings* __settings_gen_native = &settings)
-                    {
-                        __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QuicBuffer*, uint, QuicSettings*, uint, IntPtr, IntPtr*, uint>)_functionPointer)(__registrationContext_gen_native, alpnBuffers, alpnBufferCount, __settings_gen_native, settingsSize, context, &__configuration_gen_native);
-                    }
-
-                    __invokeSucceeded = true;
-                }
-                finally
-                {
-                    if (__invokeSucceeded)
-                    {
-                        //
-                        // GuaranteedUnmarshal
-                        //
-                        Marshal.InitHandle(configuration__newHandle, __configuration_gen_native);
-                        configuration = configuration__newHandle;
-                    }
-
-                    //
-                    // Cleanup
-                    //
-                    if (registrationContext__addRefd)
-                        registrationContext.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint ConfigurationLoadCredential(SafeMsQuicConfigurationHandle configuration, ref CredentialConfig credConfig)
-            {
-                CredentialConfig.Native __credConfig_gen_native = default;
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool configuration__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    configuration.DangerousAddRef(ref configuration__addRefd);
-                    IntPtr __configuration_gen_native = configuration.DangerousGetHandle();
-                    __credConfig_gen_native = new CredentialConfig.Native(credConfig);
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, CredentialConfig.Native*, uint>)_functionPointer)(__configuration_gen_native, &__credConfig_gen_native);
-                    //
-                    // Unmarshal
-                    //
-                    credConfig = __credConfig_gen_native.ToManaged();
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (configuration__addRefd)
-                        configuration.DangerousRelease();
-                    __credConfig_gen_native.FreeNative();
-                }
-
-                return __retVal;
-            }
-            internal uint ListenerOpen(SafeMsQuicRegistrationHandle registration, ListenerCallbackDelegate handler, IntPtr context, out SafeMsQuicListenerHandle listener)
-            {
-                IntPtr __handler_gen_native = default;
-                listener = default!;
-                IntPtr __listener_gen_native = default;
-                uint __retVal;
-                bool __invokeSucceeded = default;
-                //
-                // Setup
-                //
-                bool registration__addRefd = false;
-                SafeMsQuicListenerHandle listener__newHandle = new SafeMsQuicListenerHandle();
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    registration.DangerousAddRef(ref registration__addRefd);
-                    IntPtr __registration_gen_native = registration.DangerousGetHandle();
-                    __handler_gen_native = handler != null ? Marshal.GetFunctionPointerForDelegate(handler) : default;
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, IntPtr*, uint>)_functionPointer)(__registration_gen_native, __handler_gen_native, context, &__listener_gen_native);
-                    __invokeSucceeded = true;
-                    //
-                    // KeepAlive
-                    //
-                    GC.KeepAlive(handler);
-                }
-                finally
-                {
-                    if (__invokeSucceeded)
-                    {
-                        //
-                        // GuaranteedUnmarshal
-                        //
-                        Marshal.InitHandle(listener__newHandle, __listener_gen_native);
-                        listener = listener__newHandle;
-                    }
-
-                    //
-                    // Cleanup
-                    //
-                    if (registration__addRefd)
-                        registration.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint ListenerStart(SafeMsQuicListenerHandle listener, QuicBuffer* alpnBuffers, uint alpnBufferCount, byte* localAddress)
-            {
-                IntPtr __listener_gen_native;
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool listener__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    listener.DangerousAddRef(ref listener__addRefd);
-                    __listener_gen_native = listener.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QuicBuffer*, uint, byte*, uint>)_functionPointer)(__listener_gen_native, alpnBuffers, alpnBufferCount, localAddress);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (listener__addRefd)
-                        listener.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal void ListenerStop(SafeMsQuicListenerHandle listener)
-            {
-                //
-                // Setup
-                //
-                bool listener__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    listener.DangerousAddRef(ref listener__addRefd);
-                    IntPtr __listener_gen_native = listener.DangerousGetHandle();
-                    ((delegate* unmanaged[Cdecl]<IntPtr, void>)_functionPointer)(__listener_gen_native);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (listener__addRefd)
-                        listener.DangerousRelease();
-                }
-            }
-            internal uint ConnectionOpen(SafeMsQuicRegistrationHandle registration, ConnectionCallbackDelegate handler, IntPtr context, out SafeMsQuicConnectionHandle connection)
-            {
-                IntPtr __handler_gen_native = default;
-                connection = default!;
-                IntPtr __connection_gen_native = default;
-                uint __retVal;
-                bool __invokeSucceeded = default;
-                //
-                // Setup
-                //
-                bool registration__addRefd = false;
-                SafeMsQuicConnectionHandle connection__newHandle = new SafeMsQuicConnectionHandle();
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    registration.DangerousAddRef(ref registration__addRefd);
-                    IntPtr __registration_gen_native = registration.DangerousGetHandle();
-                    __handler_gen_native = handler != null ? Marshal.GetFunctionPointerForDelegate(handler) : default;
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, IntPtr*, uint>)_functionPointer)(__registration_gen_native, __handler_gen_native, context, &__connection_gen_native);
-                    __invokeSucceeded = true;
-                    //
-                    // KeepAlive
-                    //
-                    GC.KeepAlive(handler);
-                }
-                finally
-                {
-                    if (__invokeSucceeded)
-                    {
-                        //
-                        // GuaranteedUnmarshal
-                        //
-                        Marshal.InitHandle(connection__newHandle, __connection_gen_native);
-                        connection = connection__newHandle;
-                    }
-
-                    //
-                    // Cleanup
-                    //
-                    if (registration__addRefd)
-                        registration.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint ConnectionSetConfiguration(SafeMsQuicConnectionHandle connection, SafeMsQuicConfigurationHandle configuration)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool connection__addRefd = false;
-                bool configuration__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    connection.DangerousAddRef(ref connection__addRefd);
-                    IntPtr __connection_gen_native = connection.DangerousGetHandle();
-                    configuration.DangerousAddRef(ref configuration__addRefd);
-                    IntPtr __configuration_gen_native = configuration.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, uint>)_functionPointer)(__connection_gen_native, __configuration_gen_native);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (connection__addRefd)
-                        connection.DangerousRelease();
-                    if (configuration__addRefd)
-                        configuration.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint ConnectionStart(SafeMsQuicConnectionHandle connection, SafeMsQuicConfigurationHandle configuration, QUIC_ADDRESS_FAMILY family, string serverName, ushort serverPort)
-            {
-                IntPtr __connection_gen_native = default;
-                IntPtr __configuration_gen_native = default;
-                byte* __serverName_gen_native = default;
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool connection__addRefd = false;
-                bool configuration__addRefd = false;
-                bool __serverName_gen_native__allocated = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    connection.DangerousAddRef(ref connection__addRefd);
-                    __connection_gen_native = connection.DangerousGetHandle();
-                    configuration.DangerousAddRef(ref configuration__addRefd);
-                    __configuration_gen_native = configuration.DangerousGetHandle();
-                    if (serverName != null)
-                    {
-                        int __serverName_gen_native__bytelen = (serverName.Length + 1) * 3 + 1;
-                        if (__serverName_gen_native__bytelen > 260)
-                        {
-                            __serverName_gen_native = (byte*)Marshal.StringToCoTaskMemUTF8(serverName);
-                            __serverName_gen_native__allocated = true;
-                        }
-                        else
-                        {
-                            byte* __serverName_gen_native__stackptr = stackalloc byte[__serverName_gen_native__bytelen];
-                            {
-                                __serverName_gen_native__bytelen = Text.Encoding.UTF8.GetBytes(serverName, new Span<byte>(__serverName_gen_native__stackptr, __serverName_gen_native__bytelen));
-                                __serverName_gen_native__stackptr[__serverName_gen_native__bytelen] = 0;
-                            }
-
-                            __serverName_gen_native = (byte*)__serverName_gen_native__stackptr;
-                        }
-                    }
-
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, IntPtr, QUIC_ADDRESS_FAMILY, byte*, ushort, uint>)_functionPointer)(__connection_gen_native, __configuration_gen_native, family, __serverName_gen_native, serverPort);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (connection__addRefd)
-                        connection.DangerousRelease();
-                    if (configuration__addRefd)
-                        configuration.DangerousRelease();
-                    if (__serverName_gen_native__allocated)
-                    {
-                        Marshal.FreeCoTaskMem((IntPtr)__serverName_gen_native);
-                    }
-                }
-
-                return __retVal;
-            }
-            internal void ConnectionShutdown(SafeMsQuicConnectionHandle connection, QUIC_CONNECTION_SHUTDOWN_FLAGS flags, long errorCode)
-            {
-                //
-                // Setup
-                //
-                bool connection__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    connection.DangerousAddRef(ref connection__addRefd);
-                    IntPtr __connection_gen_native = connection.DangerousGetHandle();
-                    ((delegate* unmanaged[Cdecl]<IntPtr, QUIC_CONNECTION_SHUTDOWN_FLAGS, long, void>)_functionPointer)(__connection_gen_native, flags, errorCode);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (connection__addRefd)
-                        connection.DangerousRelease();
-                }
-            }
-            internal uint StreamOpen(SafeMsQuicConnectionHandle connection, QUIC_STREAM_OPEN_FLAGS flags, StreamCallbackDelegate handler, IntPtr context, out SafeMsQuicStreamHandle stream)
-            {
-                IntPtr __handler_gen_native = default;
-                stream = default!;
-                IntPtr __stream_gen_native = default;
-                uint __retVal;
-                bool __invokeSucceeded = default;
-                //
-                // Setup
-                //
-                bool connection__addRefd = false;
-                SafeMsQuicStreamHandle stream__newHandle = new SafeMsQuicStreamHandle();
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    connection.DangerousAddRef(ref connection__addRefd);
-                    IntPtr __connection_gen_native = connection.DangerousGetHandle();
-                    __handler_gen_native = handler != null ? Marshal.GetFunctionPointerForDelegate(handler) : default;
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QUIC_STREAM_OPEN_FLAGS, IntPtr, IntPtr, IntPtr*, uint>)_functionPointer)(__connection_gen_native, flags, __handler_gen_native, context, &__stream_gen_native);
-                    __invokeSucceeded = true;
-                    //
-                    // KeepAlive
-                    //
-                    GC.KeepAlive(handler);
-                }
-                finally
-                {
-                    if (__invokeSucceeded)
-                    {
-                        //
-                        // GuaranteedUnmarshal
-                        //
-                        Marshal.InitHandle(stream__newHandle, __stream_gen_native);
-                        stream = stream__newHandle;
-                    }
-
-                    //
-                    // Cleanup
-                    //
-                    if (connection__addRefd)
-                        connection.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint StreamStart(SafeMsQuicStreamHandle stream, QUIC_STREAM_START_FLAGS flags)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool stream__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    stream.DangerousAddRef(ref stream__addRefd);
-                    IntPtr __stream_gen_native = stream.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QUIC_STREAM_START_FLAGS, uint>)_functionPointer)(__stream_gen_native, flags);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (stream__addRefd)
-                        stream.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint StreamShutdown(SafeMsQuicStreamHandle stream, QUIC_STREAM_SHUTDOWN_FLAGS flags, long errorCode)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool stream__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    stream.DangerousAddRef(ref stream__addRefd);
-                    IntPtr __stream_gen_native = stream.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QUIC_STREAM_SHUTDOWN_FLAGS, long, uint>)_functionPointer)(__stream_gen_native, flags, errorCode);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (stream__addRefd)
-                        stream.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal uint StreamSend(SafeMsQuicStreamHandle stream, QuicBuffer* buffers, uint bufferCount, QUIC_SEND_FLAGS flags, IntPtr clientSendContext)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool stream__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    stream.DangerousAddRef(ref stream__addRefd);
-                    IntPtr __stream_gen_native = stream.DangerousGetHandle();
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, QuicBuffer*, uint, QUIC_SEND_FLAGS, IntPtr, uint>)_functionPointer)(__stream_gen_native, buffers, bufferCount, flags, clientSendContext);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (stream__addRefd)
-                        stream.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-            internal void StreamReceiveComplete(SafeMsQuicStreamHandle stream, ulong bufferLength)
-            {
-                //
-                // Setup
-                //
-                bool stream__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    stream.DangerousAddRef(ref stream__addRefd);
-                    IntPtr __stream_gen_native = stream.DangerousGetHandle();
-                    ((delegate* unmanaged[Cdecl]<IntPtr, ulong, void>)_functionPointer)(__stream_gen_native, bufferLength);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (stream__addRefd)
-                        stream.DangerousRelease();
-                }
-            }
-            internal uint StreamReceiveSetEnabled(SafeMsQuicStreamHandle stream, bool enabled)
-            {
-                uint __retVal;
-                //
-                // Setup
-                //
-                bool stream__addRefd = false;
-                try
-                {
-                    //
-                    // Marshal
-                    //
-                    stream.DangerousAddRef(ref stream__addRefd);
-                    IntPtr __stream_gen_native = stream.DangerousGetHandle();
-                    byte __enabled_gen_native = (byte)(enabled ? 1 : 0);
-                    __retVal = ((delegate* unmanaged[Cdecl]<IntPtr, byte, uint>)_functionPointer)(__stream_gen_native, __enabled_gen_native);
-                }
-                finally
-                {
-                    //
-                    // Cleanup
-                    //
-                    if (stream__addRefd)
-                        stream.DangerousRelease();
-                }
-
-                return __retVal;
-            }
-        }
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicSafeHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicSafeHandle.cs
new file mode 100644 (file)
index 0000000..9b2095b
--- /dev/null
@@ -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.
+
+using System.Runtime.InteropServices;
+using Microsoft.Quic;
+
+namespace System.Net.Quic.Implementations.MsQuic.Internal
+{
+    internal abstract class MsQuicSafeHandle : SafeHandle
+    {
+        // The index must corespond to SafeHandleType enum value and the value must correspond to MsQuic logging abbreviation string.
+        // This is used for our logging that uses the same format of object identification as MsQuic to easily correlate log events.
+        private static readonly string[] TypeName = new string[]
+        {
+            " reg",
+            "cnfg",
+            "list",
+            "conn",
+            "strm"
+        };
+
+        private readonly Action<IntPtr> _releaseAction;
+        private readonly string _traceId;
+
+        public override bool IsInvalid => handle == IntPtr.Zero;
+
+        public unsafe QUIC_HANDLE* QuicHandle => (QUIC_HANDLE*)DangerousGetHandle();
+
+        protected unsafe MsQuicSafeHandle(QUIC_HANDLE* handle, Action<IntPtr> releaseAction, SafeHandleType safeHandleType)
+            : base((IntPtr)handle, ownsHandle: true)
+        {
+            _releaseAction = releaseAction;
+            _traceId = $"[{TypeName[(int)safeHandleType]}][0x{DangerousGetHandle():X11}]";
+
+            if (NetEventSource.Log.IsEnabled())
+            {
+                NetEventSource.Info(this, "MsQuicSafeHandle created");
+            }
+        }
+
+        protected override bool ReleaseHandle()
+        {
+            _releaseAction(handle);
+            SetHandle(IntPtr.Zero);
+
+            if (NetEventSource.Log.IsEnabled())
+            {
+                NetEventSource.Info(this, "MsQuicSafeHandle released");
+            }
+
+            return true;
+        }
+
+        public override string ToString() => _traceId;
+    }
+
+    internal enum SafeHandleType
+    {
+        Registration,
+        Configuration,
+        Listener,
+        Connection,
+        Stream
+    }
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Linux.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Linux.cs
deleted file mode 100644 (file)
index d99df79..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static partial class MsQuicStatusCodes
-    {
-        internal const uint Success = 0;
-        internal const uint Pending = unchecked((uint)-2);
-        internal const uint Continue = unchecked((uint)-1);
-        internal const uint OutOfMemory = 12;           // ENOMEM
-        internal const uint InvalidParameter = 22;      // EINVAL
-        internal const uint InvalidState = 1;           // EPERM
-        internal const uint NotSupported = 95;          // EOPNOTSUPP
-        internal const uint NotFound = 2;               // ENOENT
-        internal const uint BufferTooSmall = 75;        // EOVERFLOW
-        internal const uint HandshakeFailure = 103;     // ECONNABORTED
-        internal const uint Aborted = 125;              // ECANCELED
-        internal const uint AddressInUse = 98;          // EADDRINUSE
-        internal const uint ConnectionTimeout = 110;    // ETIMEDOUT
-        internal const uint ConnectionIdle = 62;        // ETIME
-        internal const uint HostUnreachable = 113;      // EHOSTUNREACH
-        internal const uint InternalError = 5;          // EIO
-        internal const uint ConnectionRefused = 111;    // ECONNREFUSED
-        internal const uint ProtocolError = 71;         // EPROTO
-        internal const uint VerNegError = 93;           // EPROTONOSUPPORT
-        internal const uint TlsError = 126;             // ENOKEY
-        internal const uint UserCanceled = 130;         // EOWNERDEAD
-        internal const uint AlpnNegotiationFailure = 92;// ENOPROTOOPT
-        internal const uint StreamLimit = 86;           // ESTRPIPE
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.OSX.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.OSX.cs
deleted file mode 100644 (file)
index 03fc254..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static partial class MsQuicStatusCodes
-    {
-        internal const uint Success = 0;
-        internal const uint Pending = unchecked((uint)-2);
-        internal const uint Continue = unchecked((uint)-1);
-        internal const uint OutOfMemory = 12;           // ENOMEM
-        internal const uint InvalidParameter = 22;      // EINVAL
-        internal const uint InvalidState = 1;           // EPERM
-        internal const uint NotSupported = 102;         // EOPNOTSUPP
-        internal const uint NotFound = 2;               // ENOENT
-        internal const uint BufferTooSmall = 84;        // EOVERFLOW
-        internal const uint HandshakeFailure = 53;      // ECONNABORTED
-        internal const uint Aborted = 89;               // ECANCELED
-        internal const uint AddressInUse = 48;          // EADDRINUSE
-        internal const uint ConnectionTimeout = 60;     // ETIMEDOUT
-        internal const uint ConnectionIdle = 101;       // ETIME
-        internal const uint HostUnreachable = 65;       // EHOSTUNREACH
-        internal const uint InternalError = 5;          // EIO
-        internal const uint ConnectionRefused = 61;     // ECONNREFUSED
-        internal const uint ProtocolError = 100;        // EPROTO
-        internal const uint VerNegError = 43;           // EPROTONOSUPPORT
-        internal const uint TlsError = 126;             // ENOKEY Linux value
-        internal const uint UserCanceled = 105;         // EOWNERDEAD
-        internal const uint AlpnNegotiationFailure = 42;// ENOPROTOOPT
-        internal const uint StreamLimit = 86;           // ESTRPIPE Linux value
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Windows.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.Windows.cs
deleted file mode 100644 (file)
index 003aaa8..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static partial class MsQuicStatusCodes
-    {
-        internal const uint Success = 0;
-        internal const uint Pending = 0x703E5;
-        internal const uint Continue = 0x704DE;
-        internal const uint OutOfMemory = 0x8007000E;
-        internal const uint InvalidParameter = 0x80070057;
-        internal const uint InvalidState = 0x8007139F;
-        internal const uint NotSupported = 0x80004002;
-        internal const uint NotFound = 0x80070490;
-        internal const uint BufferTooSmall = 0x8007007A;
-        internal const uint HandshakeFailure = 0x80410000;
-        internal const uint Aborted = 0x80004004;
-        internal const uint AddressInUse = 0x80072740;
-        internal const uint ConnectionTimeout = 0x80410006;
-        internal const uint ConnectionIdle = 0x80410005;
-        internal const uint HostUnreachable = 0x800704D0;
-        internal const uint InternalError = 0x80410003;
-        internal const uint ConnectionRefused = 0x800704C9;
-        internal const uint ProtocolError = 0x80410004;
-        internal const uint VerNegError = 0x80410001;
-        internal const uint TlsError = 0x80072B18;
-        internal const uint UserCanceled = 0x80410002;
-        internal const uint AlpnNegotiationFailure = 0x80410007;
-        internal const uint StreamLimit = 0x80410008;
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusCodes.cs
deleted file mode 100644 (file)
index 50bc061..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static partial class MsQuicStatusCodes
-    {
-        // TODO return better error messages here.
-        public static string GetError(uint status)
-        {
-            return status switch
-            {
-                Success => "SUCCESS",
-                Pending => "PENDING",
-                Continue => "CONTINUE",
-                OutOfMemory => "OUT_OF_MEMORY",
-                InvalidParameter => "INVALID_PARAMETER",
-                InvalidState => "INVALID_STATE",
-                NotSupported => "NOT_SUPPORTED",
-                NotFound => "NOT_FOUND",
-                BufferTooSmall => "BUFFER_TOO_SMALL",
-                HandshakeFailure => "HANDSHAKE_FAILURE",
-                Aborted => "ABORTED",
-                AddressInUse => "ADDRESS_IN_USE",
-                ConnectionTimeout => "CONNECTION_TIMEOUT",
-                ConnectionIdle => "CONNECTION_IDLE",
-                HostUnreachable => "UNREACHABLE",
-                InternalError => "INTERNAL_ERROR",
-                ConnectionRefused => "CONNECTION_REFUSED",
-                ProtocolError => "PROTOCOL_ERROR",
-                VerNegError => "VER_NEG_ERROR",
-                TlsError => "TLS_ERROR",
-                UserCanceled => "USER_CANCELED",
-                AlpnNegotiationFailure => "ALPN_NEG_FAILURE",
-                StreamLimit => "STREAM_LIMIT_REACHED",
-                _ => $"0x{status:X8}"
-            };
-        }
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusHelper.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicStatusHelper.cs
deleted file mode 100644 (file)
index 4f2bedb..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static class MsQuicStatusHelper
-    {
-        internal static bool SuccessfulStatusCode(uint status)
-        {
-            if (OperatingSystem.IsWindows())
-            {
-                return status < 0x80000000;
-            }
-
-            if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
-            {
-                return (int)status <= 0;
-            }
-
-            return false;
-        }
-    }
-}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicTraceHelper.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicTraceHelper.cs
deleted file mode 100644 (file)
index cd7b4ba..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Runtime.InteropServices;
-
-namespace System.Net.Quic.Implementations.MsQuic.Internal
-{
-    internal static class MsQuicTraceHelper
-    {
-        internal static string GetTraceId(SafeMsQuicStreamHandle handle)
-        {
-            return $"[strm][0x{GetIntPtrHex(handle)}]";
-        }
-
-        internal static string GetTraceId(SafeMsQuicConnectionHandle handle)
-        {
-            return $"[conn][0x{GetIntPtrHex(handle)}]";
-        }
-
-        internal static string GetTraceId(SafeMsQuicListenerHandle handle)
-        {
-            return $"[list][0x{GetIntPtrHex(handle)}]";
-        }
-
-        private static string GetIntPtrHex(SafeHandle handle)
-        {
-            return handle.DangerousGetHandle().ToString("X11");
-        }
-    }
-}
index adcce1b..a04f131 100644 (file)
@@ -8,25 +8,17 @@ using System.Net.Security;
 using System.Runtime.InteropServices;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
+using Microsoft.Quic;
+using static Microsoft.Quic.MsQuic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
-    internal sealed class SafeMsQuicConfigurationHandle : SafeHandle
+    internal sealed class SafeMsQuicConfigurationHandle : MsQuicSafeHandle
     {
-        public override bool IsInvalid => handle == IntPtr.Zero;
-
-        public SafeMsQuicConfigurationHandle()
-            : base(IntPtr.Zero, ownsHandle: true)
+        public unsafe SafeMsQuicConfigurationHandle(QUIC_HANDLE* handle)
+            : base(handle, ptr => MsQuicApi.Api.ApiTable->ConfigurationClose((QUIC_HANDLE*)ptr), SafeHandleType.Configuration)
         { }
 
-        protected override bool ReleaseHandle()
-        {
-            MsQuicApi.Api.ConfigurationCloseDelegate(handle);
-            SetHandle(IntPtr.Zero);
-            return true;
-        }
-
         // TODO: consider moving the static code from here to keep all the handle classes small and simple.
         public static SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions options)
         {
@@ -130,50 +122,42 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
 
             Debug.Assert(!MsQuicApi.Api.Registration.IsInvalid);
 
-            var settings = new QuicSettings
-            {
-                IsSetFlags = QuicSettingsIsSetFlags.PeerBidiStreamCount |
-                             QuicSettingsIsSetFlags.PeerUnidiStreamCount,
-                PeerBidiStreamCount = (ushort)options.MaxBidirectionalStreams,
-                PeerUnidiStreamCount = (ushort)options.MaxUnidirectionalStreams
-            };
+            QUIC_SETTINGS settings = default(QUIC_SETTINGS);
+            settings.IsSet.PeerUnidiStreamCount = 1;
+            settings.PeerUnidiStreamCount = (ushort)options.MaxUnidirectionalStreams;
+            settings.IsSet.PeerBidiStreamCount = 1;
+            settings.PeerBidiStreamCount = (ushort)options.MaxBidirectionalStreams;
 
+            settings.IsSet.IdleTimeoutMs = 1;
             if (options.IdleTimeout != Timeout.InfiniteTimeSpan)
             {
                 if (options.IdleTimeout <= TimeSpan.Zero) throw new Exception("IdleTimeout must not be negative.");
-
-                ulong ms = (ulong)options.IdleTimeout.Ticks / TimeSpan.TicksPerMillisecond;
-                if (ms > (1ul << 62) - 1) throw new Exception("IdleTimeout is too large (max 2^62-1 milliseconds)");
-
                 settings.IdleTimeoutMs = (ulong)options.IdleTimeout.TotalMilliseconds;
             }
             else
             {
                 settings.IdleTimeoutMs = 0;
             }
-            settings.IsSetFlags |= QuicSettingsIsSetFlags.IdleTimeoutMs;
 
-            uint status;
-            SafeMsQuicConfigurationHandle? configurationHandle;
+            SafeMsQuicConfigurationHandle configurationHandle;
             X509Certificate2[]? intermediates = null;
 
-            MemoryHandle[]? handles = null;
-            QuicBuffer[]? buffers = null;
-            try
-            {
-                MsQuicAlpnHelper.Prepare(alpnProtocols, out handles, out buffers);
-                status = MsQuicApi.Api.ConfigurationOpenDelegate(MsQuicApi.Api.Registration, (QuicBuffer*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)alpnProtocols.Count, ref settings, (uint)sizeof(QuicSettings), context: IntPtr.Zero, out configurationHandle);
-            }
-            finally
-            {
-                MsQuicAlpnHelper.Return(ref handles, ref buffers);
-            }
-
-            QuicExceptionHelpers.ThrowIfFailed(status, "ConfigurationOpen failed.");
+            QUIC_HANDLE* handle;
+            using var msquicBuffers = new MsQuicBuffers();
+            msquicBuffers.Initialize(alpnProtocols, alpnProtocol => alpnProtocol.Protocol);
+            ThrowIfFailure(MsQuicApi.Api.ApiTable->ConfigurationOpen(
+                MsQuicApi.Api.Registration.QuicHandle,
+                msquicBuffers.Buffers,
+                (uint)alpnProtocols.Count,
+                &settings,
+                (uint)sizeof(QUIC_SETTINGS),
+                (void*)IntPtr.Zero,
+                &handle), "ConfigurationOpen failed");
+            configurationHandle = new SafeMsQuicConfigurationHandle(handle);
 
             try
             {
-                CredentialConfig config = default;
+                QUIC_CREDENTIAL_CONFIG config = default;
                 config.Flags = flags; // TODO: consider using LOAD_ASYNCHRONOUS with a callback.
 
                 if (cipherSuitesPolicy != null)
@@ -188,17 +172,17 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
                     intermediates = certificateContext.IntermediateCertificates;
                 }
 
+                int status;
                 if (certificate != null)
                 {
                     if (OperatingSystem.IsWindows())
                     {
-                        config.Type = QUIC_CREDENTIAL_TYPE.CONTEXT;
-                        config.Certificate = certificate.Handle;
-                        status = MsQuicApi.Api.ConfigurationLoadCredentialDelegate(configurationHandle, ref config);
+                        config.Type = QUIC_CREDENTIAL_TYPE.CERTIFICATE_CONTEXT;
+                        config.CertificateContext = (void*)certificate.Handle;
+                        status = MsQuicApi.Api.ApiTable->ConfigurationLoadCredential(configurationHandle.QuicHandle, &config);
                     }
                     else
                     {
-                        CredentialConfigCertificatePkcs12 pkcs12Config;
                         byte[] asn1;
 
                         if (intermediates?.Length > 0)
@@ -217,32 +201,35 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
                             asn1 = certificate.Export(X509ContentType.Pkcs12);
                         }
 
-                        fixed (void* ptr = asn1)
+                        fixed (byte* ptr = asn1)
                         {
-                            pkcs12Config.Asn1Blob = (IntPtr)ptr;
-                            pkcs12Config.Asn1BlobLength = (uint)asn1.Length;
-                            pkcs12Config.PrivateKeyPassword = IntPtr.Zero;
-
-                            config.Type = QUIC_CREDENTIAL_TYPE.PKCS12;
-                            config.Certificate = (IntPtr)(&pkcs12Config);
-                            status = MsQuicApi.Api.ConfigurationLoadCredentialDelegate(configurationHandle, ref config);
+                            QUIC_CERTIFICATE_PKCS12 pkcs12Config = new QUIC_CERTIFICATE_PKCS12
+                            {
+                                Asn1Blob = ptr,
+                                Asn1BlobLength = (uint)asn1.Length,
+                                PrivateKeyPassword = (sbyte*)IntPtr.Zero
+                            };
+
+                            config.Type = QUIC_CREDENTIAL_TYPE.CERTIFICATE_PKCS12;
+                            config.CertificatePkcs12 = &pkcs12Config;
+                            status = MsQuicApi.Api.ApiTable->ConfigurationLoadCredential(configurationHandle.QuicHandle, &config);
                         }
                     }
                 }
                 else
                 {
                     config.Type = QUIC_CREDENTIAL_TYPE.NONE;
-                    status = MsQuicApi.Api.ConfigurationLoadCredentialDelegate(configurationHandle, ref config);
+                    status = MsQuicApi.Api.ApiTable->ConfigurationLoadCredential(configurationHandle.QuicHandle, &config);
                 }
 
 #if TARGET_WINDOWS
                 if ((Interop.SECURITY_STATUS)status == Interop.SECURITY_STATUS.AlgorithmMismatch && MsQuicApi.Tls13MayBeDisabled)
                 {
-                    throw new QuicException(SR.net_ssl_app_protocols_invalid, null, (int)status);
+                    throw new MsQuicException(status, SR.net_ssl_app_protocols_invalid);
                 }
 #endif
 
-                QuicExceptionHelpers.ThrowIfFailed(status, "ConfigurationLoadCredential failed.");
+                ThrowIfFailure(status, "ConfigurationLoadCredential failed");
             }
             catch
             {
index 9354ce0..4d308bd 100644 (file)
@@ -1,29 +1,14 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Runtime.InteropServices;
+using Microsoft.Quic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
-    internal sealed class SafeMsQuicConnectionHandle : SafeHandle
+    internal sealed class SafeMsQuicConnectionHandle : MsQuicSafeHandle
     {
-        public override bool IsInvalid => handle == IntPtr.Zero;
-
-        public SafeMsQuicConnectionHandle()
-            : base(IntPtr.Zero, ownsHandle: true)
+        public unsafe SafeMsQuicConnectionHandle(QUIC_HANDLE* handle)
+            : base(handle, ptr => MsQuicApi.Api.ApiTable->ConnectionClose((QUIC_HANDLE*)ptr), SafeHandleType.Connection)
         { }
-
-        public SafeMsQuicConnectionHandle(IntPtr connectionHandle)
-            : this()
-        {
-            SetHandle(connectionHandle);
-        }
-
-        protected override bool ReleaseHandle()
-        {
-            MsQuicApi.Api.ConnectionCloseDelegate(handle);
-            SetHandle(IntPtr.Zero);
-            return true;
-        }
     }
 }
index f0f7555..1188efd 100644 (file)
@@ -1,23 +1,14 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Runtime.InteropServices;
+using Microsoft.Quic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
-    internal sealed class SafeMsQuicListenerHandle : SafeHandle
+    internal sealed class SafeMsQuicListenerHandle : MsQuicSafeHandle
     {
-        public override bool IsInvalid => handle == IntPtr.Zero;
-
-        public SafeMsQuicListenerHandle()
-            : base(IntPtr.Zero, ownsHandle: true)
+        public unsafe SafeMsQuicListenerHandle(QUIC_HANDLE* handle)
+            : base(handle, ptr => MsQuicApi.Api.ApiTable->ListenerClose((QUIC_HANDLE*)ptr), SafeHandleType.Listener)
         { }
-
-        protected override bool ReleaseHandle()
-        {
-            MsQuicApi.Api.ListenerCloseDelegate(handle);
-            SetHandle(IntPtr.Zero);
-            return true;
-        }
     }
 }
index 798636b..629946e 100644 (file)
@@ -1,23 +1,14 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Runtime.InteropServices;
+using Microsoft.Quic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
-    internal sealed class SafeMsQuicRegistrationHandle : SafeHandle
+    internal sealed class SafeMsQuicRegistrationHandle : MsQuicSafeHandle
     {
-        public override bool IsInvalid => handle == IntPtr.Zero;
-
-        public SafeMsQuicRegistrationHandle()
-            : base(IntPtr.Zero, ownsHandle: true)
+        public unsafe SafeMsQuicRegistrationHandle(QUIC_HANDLE* handle)
+            : base(handle, ptr => MsQuicApi.Api.ApiTable->RegistrationClose((QUIC_HANDLE*)ptr), SafeHandleType.Registration)
         { }
-
-        protected override bool ReleaseHandle()
-        {
-            MsQuicApi.Api.RegistrationCloseDelegate(handle);
-            SetHandle(IntPtr.Zero);
-            return true;
-        }
     }
 }
index 179bdd3..4cbf56d 100644 (file)
@@ -1,29 +1,14 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Runtime.InteropServices;
+using Microsoft.Quic;
 
 namespace System.Net.Quic.Implementations.MsQuic.Internal
 {
-    internal sealed class SafeMsQuicStreamHandle : SafeHandle
+    internal sealed class SafeMsQuicStreamHandle : MsQuicSafeHandle
     {
-        public override bool IsInvalid => handle == IntPtr.Zero;
-
-        public SafeMsQuicStreamHandle()
-            : base(IntPtr.Zero, ownsHandle: true)
+        public unsafe SafeMsQuicStreamHandle(QUIC_HANDLE* handle)
+            : base(handle, ptr => MsQuicApi.Api.ApiTable->StreamClose((QUIC_HANDLE*)ptr), SafeHandleType.Stream)
         { }
-
-        public SafeMsQuicStreamHandle(IntPtr streamHandle)
-            : this()
-        {
-            SetHandle(streamHandle);
-        }
-
-        protected override bool ReleaseHandle()
-        {
-            MsQuicApi.Api.StreamCloseDelegate(handle);
-            SetHandle(IntPtr.Zero);
-            return true;
-        }
     }
 }
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic.cs
new file mode 100644 (file)
index 0000000..96b83d6
--- /dev/null
@@ -0,0 +1,192 @@
+#pragma warning disable IDE0073
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+//
+#pragma warning restore IDE0073
+
+using System;
+using System.Diagnostics;
+using System.Net.Quic;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.Quic
+{
+    internal unsafe partial struct QUIC_BUFFER
+    {
+        public Span<byte> Span => new(Buffer, (int)Length);
+    }
+
+    internal partial class MsQuic
+    {
+        public static unsafe QUIC_API_TABLE* Open()
+        {
+            QUIC_API_TABLE* ApiTable;
+            int Status = MsQuicOpenVersion(2, (void**)&ApiTable);
+            ThrowIfFailure(Status);
+            return ApiTable;
+        }
+
+        public static unsafe void Close(QUIC_API_TABLE* ApiTable)
+        {
+            MsQuicClose(ApiTable);
+        }
+
+        public static void ThrowIfFailure(int status, string? message = null)
+        {
+            if (StatusFailed(status))
+            {
+                // TODO make custom exception, and maybe throw helpers
+                throw new MsQuicException(status, message);
+            }
+        }
+
+        public static bool StatusSucceeded(int status)
+        {
+            if (OperatingSystem.IsWindows())
+            {
+                return status >= 0;
+            }
+            else
+            {
+                return status <= 0;
+            }
+        }
+
+        public static bool StatusFailed(int status)
+        {
+            if (OperatingSystem.IsWindows())
+            {
+                return status < 0;
+            }
+            else
+            {
+                return status > 0;
+            }
+        }
+
+        public static int QUIC_STATUS_SUCCESS => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_SUCCESS : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_SUCCESS : MsQuic_MacOS.QUIC_STATUS_SUCCESS;
+        public static int QUIC_STATUS_PENDING => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_PENDING : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_PENDING : MsQuic_Linux.QUIC_STATUS_PENDING;
+        public static int QUIC_STATUS_CONTINUE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CONTINUE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CONTINUE : MsQuic_Linux.QUIC_STATUS_CONTINUE;
+        public static int QUIC_STATUS_OUT_OF_MEMORY => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_OUT_OF_MEMORY : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_OUT_OF_MEMORY : MsQuic_Linux.QUIC_STATUS_OUT_OF_MEMORY;
+        public static int QUIC_STATUS_INVALID_PARAMETER => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_INVALID_PARAMETER : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_INVALID_PARAMETER : MsQuic_Linux.QUIC_STATUS_INVALID_PARAMETER;
+        public static int QUIC_STATUS_INVALID_STATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_INVALID_STATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_INVALID_STATE : MsQuic_Linux.QUIC_STATUS_INVALID_STATE;
+        public static int QUIC_STATUS_NOT_SUPPORTED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_NOT_SUPPORTED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_NOT_SUPPORTED : MsQuic_Linux.QUIC_STATUS_NOT_SUPPORTED;
+        public static int QUIC_STATUS_NOT_FOUND => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_NOT_FOUND : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_NOT_FOUND : MsQuic_Linux.QUIC_STATUS_NOT_FOUND;
+        public static int QUIC_STATUS_BUFFER_TOO_SMALL => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_BUFFER_TOO_SMALL : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_BUFFER_TOO_SMALL : MsQuic_Linux.QUIC_STATUS_BUFFER_TOO_SMALL;
+        public static int QUIC_STATUS_HANDSHAKE_FAILURE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_HANDSHAKE_FAILURE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_HANDSHAKE_FAILURE : MsQuic_Linux.QUIC_STATUS_HANDSHAKE_FAILURE;
+        public static int QUIC_STATUS_ABORTED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_ABORTED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_ABORTED : MsQuic_Linux.QUIC_STATUS_ABORTED;
+        public static int QUIC_STATUS_ADDRESS_IN_USE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_ADDRESS_IN_USE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_ADDRESS_IN_USE : MsQuic_Linux.QUIC_STATUS_ADDRESS_IN_USE;
+        public static int QUIC_STATUS_CONNECTION_TIMEOUT => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CONNECTION_TIMEOUT : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CONNECTION_TIMEOUT : MsQuic_Linux.QUIC_STATUS_CONNECTION_TIMEOUT;
+        public static int QUIC_STATUS_CONNECTION_IDLE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CONNECTION_IDLE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CONNECTION_IDLE : MsQuic_Linux.QUIC_STATUS_CONNECTION_IDLE;
+        public static int QUIC_STATUS_UNREACHABLE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_UNREACHABLE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_UNREACHABLE : MsQuic_Linux.QUIC_STATUS_UNREACHABLE;
+        public static int QUIC_STATUS_INTERNAL_ERROR => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_INTERNAL_ERROR : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_INTERNAL_ERROR : MsQuic_Linux.QUIC_STATUS_INTERNAL_ERROR;
+        public static int QUIC_STATUS_CONNECTION_REFUSED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CONNECTION_REFUSED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CONNECTION_REFUSED : MsQuic_Linux.QUIC_STATUS_CONNECTION_REFUSED;
+        public static int QUIC_STATUS_PROTOCOL_ERROR => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_PROTOCOL_ERROR : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_PROTOCOL_ERROR : MsQuic_Linux.QUIC_STATUS_PROTOCOL_ERROR;
+        public static int QUIC_STATUS_VER_NEG_ERROR => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_VER_NEG_ERROR : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_VER_NEG_ERROR : MsQuic_Linux.QUIC_STATUS_VER_NEG_ERROR;
+        public static int QUIC_STATUS_TLS_ERROR => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_TLS_ERROR : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_TLS_ERROR : MsQuic_Linux.QUIC_STATUS_TLS_ERROR;
+        public static int QUIC_STATUS_USER_CANCELED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_USER_CANCELED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_USER_CANCELED : MsQuic_Linux.QUIC_STATUS_USER_CANCELED;
+        public static int QUIC_STATUS_ALPN_NEG_FAILURE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_ALPN_NEG_FAILURE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_ALPN_NEG_FAILURE : MsQuic_Linux.QUIC_STATUS_ALPN_NEG_FAILURE;
+        public static int QUIC_STATUS_STREAM_LIMIT_REACHED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_STREAM_LIMIT_REACHED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_STREAM_LIMIT_REACHED : MsQuic_Linux.QUIC_STATUS_STREAM_LIMIT_REACHED;
+        public static int QUIC_STATUS_CLOSE_NOTIFY => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CLOSE_NOTIFY : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CLOSE_NOTIFY : MsQuic_Linux.QUIC_STATUS_CLOSE_NOTIFY;
+        public static int QUIC_STATUS_BAD_CERTIFICATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_BAD_CERTIFICATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_BAD_CERTIFICATE : MsQuic_Linux.QUIC_STATUS_BAD_CERTIFICATE;
+        public static int QUIC_STATUS_UNSUPPORTED_CERTIFICATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_UNSUPPORTED_CERTIFICATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_UNSUPPORTED_CERTIFICATE : MsQuic_Linux.QUIC_STATUS_UNSUPPORTED_CERTIFICATE;
+        public static int QUIC_STATUS_REVOKED_CERTIFICATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_REVOKED_CERTIFICATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_REVOKED_CERTIFICATE : MsQuic_Linux.QUIC_STATUS_REVOKED_CERTIFICATE;
+        public static int QUIC_STATUS_EXPIRED_CERTIFICATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_EXPIRED_CERTIFICATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_EXPIRED_CERTIFICATE : MsQuic_Linux.QUIC_STATUS_EXPIRED_CERTIFICATE;
+        public static int QUIC_STATUS_UNKNOWN_CERTIFICATE => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_UNKNOWN_CERTIFICATE : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_UNKNOWN_CERTIFICATE : MsQuic_Linux.QUIC_STATUS_UNKNOWN_CERTIFICATE;
+        public static int QUIC_STATUS_CERT_EXPIRED => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CERT_EXPIRED : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CERT_EXPIRED : MsQuic_Linux.QUIC_STATUS_CERT_EXPIRED;
+        public static int QUIC_STATUS_CERT_UNTRUSTED_ROOT => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_STATUS_CERT_UNTRUSTED_ROOT : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_STATUS_CERT_UNTRUSTED_ROOT : MsQuic_Linux.QUIC_STATUS_CERT_UNTRUSTED_ROOT;
+
+        public static int QUIC_ADDRESS_FAMILY_UNSPEC => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_ADDRESS_FAMILY_UNSPEC : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_ADDRESS_FAMILY_UNSPEC : MsQuic_Linux.QUIC_ADDRESS_FAMILY_UNSPEC;
+        public static int QUIC_ADDRESS_FAMILY_INET => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_ADDRESS_FAMILY_INET : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_ADDRESS_FAMILY_INET : MsQuic_Linux.QUIC_ADDRESS_FAMILY_INET;
+        public static int QUIC_ADDRESS_FAMILY_INET6 => OperatingSystem.IsWindows() ? MsQuic_Windows.QUIC_ADDRESS_FAMILY_INET6 : (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) ? MsQuic_Linux.QUIC_ADDRESS_FAMILY_INET6 : MsQuic_Linux.QUIC_ADDRESS_FAMILY_INET6;
+    }
+
+    /// <summary>Defines the type of a member as it was used in the native signature.</summary>
+    [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = true)]
+    [Conditional("DEBUG")]
+    internal sealed class NativeTypeNameAttribute : Attribute
+    {
+        private readonly string _name;
+
+        /// <summary>Initializes a new instance of the <see cref="NativeTypeNameAttribute" /> class.</summary>
+        /// <param name="name">The name of the type that was used in the native signature.</param>
+        public NativeTypeNameAttribute(string name)
+        {
+            _name = name;
+        }
+
+        /// <summary>Gets the name of the type that was used in the native signature.</summary>
+        public string Name => _name;
+    }
+
+    [StructLayout(LayoutKind.Explicit)]
+    internal struct QuicAddrFamilyAndLen
+    {
+        [FieldOffset(0)]
+        public ushort sin_family;
+        [FieldOffset(0)]
+        public byte sin_len;
+        [FieldOffset(1)]
+        public byte sin_family_bsd;
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal unsafe struct QuicAddrIn
+    {
+        public QuicAddrFamilyAndLen sin_family;
+        public ushort sin_port;
+        public fixed byte sin_addr[4];
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    internal unsafe struct QuicAddrIn6
+    {
+        public QuicAddrFamilyAndLen sin6_family;
+        public ushort sin6_port;
+        public uint sin6_flowinfo;
+        public fixed byte sin6_addr[16];
+        public uint sin6_scope_id;
+    }
+
+    [StructLayout(LayoutKind.Explicit)]
+    internal struct QuicAddr
+    {
+        [FieldOffset(0)]
+        public QuicAddrIn Ipv4;
+        [FieldOffset(0)]
+        public QuicAddrIn6 Ipv6;
+        [FieldOffset(0)]
+        public QuicAddrFamilyAndLen FamilyLen;
+
+        public static bool SockaddrHasLength => OperatingSystem.IsFreeBSD() || OperatingSystem.IsIOS() || OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS();
+
+        public int Family
+        {
+            get
+            {
+                if (SockaddrHasLength)
+                {
+                    return FamilyLen.sin_family_bsd;
+                }
+                else
+                {
+                    return FamilyLen.sin_family;
+                }
+            }
+            set
+            {
+                if (SockaddrHasLength)
+                {
+                    FamilyLen.sin_family_bsd = (byte)value;
+                }
+                else
+                {
+                    FamilyLen.sin_family = (ushort)value;
+                }
+            }
+        }
+    }
+
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated.cs
new file mode 100644 (file)
index 0000000..f26a48f
--- /dev/null
@@ -0,0 +1,2677 @@
+#pragma warning disable IDE0073
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+//
+#pragma warning restore IDE0073
+
+#pragma warning disable CS0649
+
+using System.Runtime.InteropServices;
+
+namespace Microsoft.Quic
+{
+    internal partial struct QUIC_HANDLE
+    {
+    }
+
+    internal enum QUIC_EXECUTION_PROFILE
+    {
+        LOW_LATENCY,
+        MAX_THROUGHPUT,
+        SCAVENGER,
+        REAL_TIME,
+    }
+
+    internal enum QUIC_LOAD_BALANCING_MODE
+    {
+        DISABLED,
+        SERVER_ID_IP,
+    }
+
+    internal enum QUIC_CREDENTIAL_TYPE
+    {
+        NONE,
+        CERTIFICATE_HASH,
+        CERTIFICATE_HASH_STORE,
+        CERTIFICATE_CONTEXT,
+        CERTIFICATE_FILE,
+        CERTIFICATE_FILE_PROTECTED,
+        CERTIFICATE_PKCS12,
+    }
+
+    [System.Flags]
+    internal enum QUIC_CREDENTIAL_FLAGS
+    {
+        NONE = 0x00000000,
+        CLIENT = 0x00000001,
+        LOAD_ASYNCHRONOUS = 0x00000002,
+        NO_CERTIFICATE_VALIDATION = 0x00000004,
+        ENABLE_OCSP = 0x00000008,
+        INDICATE_CERTIFICATE_RECEIVED = 0x00000010,
+        DEFER_CERTIFICATE_VALIDATION = 0x00000020,
+        REQUIRE_CLIENT_AUTHENTICATION = 0x00000040,
+        USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080,
+        REVOCATION_CHECK_END_CERT = 0x00000100,
+        REVOCATION_CHECK_CHAIN = 0x00000200,
+        REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x00000400,
+        IGNORE_NO_REVOCATION_CHECK = 0x00000800,
+        IGNORE_REVOCATION_OFFLINE = 0x00001000,
+        SET_ALLOWED_CIPHER_SUITES = 0x00002000,
+        USE_PORTABLE_CERTIFICATES = 0x00004000,
+        USE_SUPPLIED_CREDENTIALS = 0x00008000,
+    }
+
+    [System.Flags]
+    internal enum QUIC_ALLOWED_CIPHER_SUITE_FLAGS
+    {
+        NONE = 0x0,
+        AES_128_GCM_SHA256 = 0x1,
+        AES_256_GCM_SHA384 = 0x2,
+        CHACHA20_POLY1305_SHA256 = 0x4,
+    }
+
+    [System.Flags]
+    internal enum QUIC_CERTIFICATE_HASH_STORE_FLAGS
+    {
+        NONE = 0x0000,
+        MACHINE_STORE = 0x0001,
+    }
+
+    [System.Flags]
+    internal enum QUIC_CONNECTION_SHUTDOWN_FLAGS
+    {
+        NONE = 0x0000,
+        SILENT = 0x0001,
+    }
+
+    internal enum QUIC_SERVER_RESUMPTION_LEVEL
+    {
+        NO_RESUME,
+        RESUME_ONLY,
+        RESUME_AND_ZERORTT,
+    }
+
+    [System.Flags]
+    internal enum QUIC_SEND_RESUMPTION_FLAGS
+    {
+        NONE = 0x0000,
+        FINAL = 0x0001,
+    }
+
+    internal enum QUIC_STREAM_SCHEDULING_SCHEME
+    {
+        FIFO = 0x0000,
+        ROUND_ROBIN = 0x0001,
+        COUNT,
+    }
+
+    [System.Flags]
+    internal enum QUIC_STREAM_OPEN_FLAGS
+    {
+        NONE = 0x0000,
+        UNIDIRECTIONAL = 0x0001,
+        ZERO_RTT = 0x0002,
+    }
+
+    [System.Flags]
+    internal enum QUIC_STREAM_START_FLAGS
+    {
+        NONE = 0x0000,
+        IMMEDIATE = 0x0001,
+        FAIL_BLOCKED = 0x0002,
+        SHUTDOWN_ON_FAIL = 0x0004,
+        INDICATE_PEER_ACCEPT = 0x0008,
+    }
+
+    [System.Flags]
+    internal enum QUIC_STREAM_SHUTDOWN_FLAGS
+    {
+        NONE = 0x0000,
+        GRACEFUL = 0x0001,
+        ABORT_SEND = 0x0002,
+        ABORT_RECEIVE = 0x0004,
+        ABORT = 0x0006,
+        IMMEDIATE = 0x0008,
+        INLINE = 0x0010,
+    }
+
+    [System.Flags]
+    internal enum QUIC_RECEIVE_FLAGS
+    {
+        NONE = 0x0000,
+        ZERO_RTT = 0x0001,
+        FIN = 0x0002,
+    }
+
+    [System.Flags]
+    internal enum QUIC_SEND_FLAGS
+    {
+        NONE = 0x0000,
+        ALLOW_0_RTT = 0x0001,
+        START = 0x0002,
+        FIN = 0x0004,
+        DGRAM_PRIORITY = 0x0008,
+        DELAY_SEND = 0x0010,
+    }
+
+    internal enum QUIC_DATAGRAM_SEND_STATE
+    {
+        UNKNOWN,
+        SENT,
+        LOST_SUSPECT,
+        LOST_DISCARDED,
+        ACKNOWLEDGED,
+        ACKNOWLEDGED_SPURIOUS,
+        CANCELED,
+    }
+
+    internal unsafe partial struct QUIC_REGISTRATION_CONFIG
+    {
+        [NativeTypeName("const char *")]
+        internal sbyte* AppName;
+
+        internal QUIC_EXECUTION_PROFILE ExecutionProfile;
+    }
+
+    internal unsafe partial struct QUIC_CERTIFICATE_HASH
+    {
+        [NativeTypeName("uint8_t [20]")]
+        internal fixed byte ShaHash[20];
+    }
+
+    internal unsafe partial struct QUIC_CERTIFICATE_HASH_STORE
+    {
+        internal QUIC_CERTIFICATE_HASH_STORE_FLAGS Flags;
+
+        [NativeTypeName("uint8_t [20]")]
+        internal fixed byte ShaHash[20];
+
+        [NativeTypeName("char [128]")]
+        internal fixed sbyte StoreName[128];
+    }
+
+    internal unsafe partial struct QUIC_CERTIFICATE_FILE
+    {
+        [NativeTypeName("const char *")]
+        internal sbyte* PrivateKeyFile;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* CertificateFile;
+    }
+
+    internal unsafe partial struct QUIC_CERTIFICATE_FILE_PROTECTED
+    {
+        [NativeTypeName("const char *")]
+        internal sbyte* PrivateKeyFile;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* CertificateFile;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* PrivateKeyPassword;
+    }
+
+    internal unsafe partial struct QUIC_CERTIFICATE_PKCS12
+    {
+        [NativeTypeName("const uint8_t *")]
+        internal byte* Asn1Blob;
+
+        [NativeTypeName("uint32_t")]
+        internal uint Asn1BlobLength;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* PrivateKeyPassword;
+    }
+
+    internal unsafe partial struct QUIC_CREDENTIAL_CONFIG
+    {
+        internal QUIC_CREDENTIAL_TYPE Type;
+
+        internal QUIC_CREDENTIAL_FLAGS Flags;
+
+        [NativeTypeName("QUIC_CREDENTIAL_CONFIG::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* Principal;
+
+        internal void* Reserved;
+
+        [NativeTypeName("QUIC_CREDENTIAL_LOAD_COMPLETE_HANDLER")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, int, void> AsyncHandler;
+
+        internal QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites;
+
+        internal ref QUIC_CERTIFICATE_HASH* CertificateHash
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificateHash;
+            }
+        }
+
+        internal ref QUIC_CERTIFICATE_HASH_STORE* CertificateHashStore
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificateHashStore;
+            }
+        }
+
+        internal ref void* CertificateContext
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificateContext;
+            }
+        }
+
+        internal ref QUIC_CERTIFICATE_FILE* CertificateFile
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificateFile;
+            }
+        }
+
+        internal ref QUIC_CERTIFICATE_FILE_PROTECTED* CertificateFileProtected
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificateFileProtected;
+            }
+        }
+
+        internal ref QUIC_CERTIFICATE_PKCS12* CertificatePkcs12
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref this, 1)).Anonymous.CertificatePkcs12;
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal unsafe partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            internal QUIC_CERTIFICATE_HASH* CertificateHash;
+
+            [FieldOffset(0)]
+            internal QUIC_CERTIFICATE_HASH_STORE* CertificateHashStore;
+
+            [FieldOffset(0)]
+            [NativeTypeName("QUIC_CERTIFICATE *")]
+            internal void* CertificateContext;
+
+            [FieldOffset(0)]
+            internal QUIC_CERTIFICATE_FILE* CertificateFile;
+
+            [FieldOffset(0)]
+            internal QUIC_CERTIFICATE_FILE_PROTECTED* CertificateFileProtected;
+
+            [FieldOffset(0)]
+            internal QUIC_CERTIFICATE_PKCS12* CertificatePkcs12;
+        }
+    }
+
+    internal unsafe partial struct QUIC_TICKET_KEY_CONFIG
+    {
+        [NativeTypeName("uint8_t [16]")]
+        internal fixed byte Id[16];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte Material[64];
+
+        [NativeTypeName("uint8_t")]
+        internal byte MaterialLength;
+    }
+
+    internal unsafe partial struct QUIC_BUFFER
+    {
+        [NativeTypeName("uint32_t")]
+        internal uint Length;
+
+        [NativeTypeName("uint8_t *")]
+        internal byte* Buffer;
+    }
+
+    internal unsafe partial struct QUIC_NEW_CONNECTION_INFO
+    {
+        [NativeTypeName("uint32_t")]
+        internal uint QuicVersion;
+
+        [NativeTypeName("const QUIC_ADDR *")]
+        internal QuicAddr* LocalAddress;
+
+        [NativeTypeName("const QUIC_ADDR *")]
+        internal QuicAddr* RemoteAddress;
+
+        [NativeTypeName("uint32_t")]
+        internal uint CryptoBufferLength;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort ClientAlpnListLength;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort ServerNameLength;
+
+        [NativeTypeName("uint8_t")]
+        internal byte NegotiatedAlpnLength;
+
+        [NativeTypeName("const uint8_t *")]
+        internal byte* CryptoBuffer;
+
+        [NativeTypeName("const uint8_t *")]
+        internal byte* ClientAlpnList;
+
+        [NativeTypeName("const uint8_t *")]
+        internal byte* NegotiatedAlpn;
+
+        [NativeTypeName("const char *")]
+        internal sbyte* ServerName;
+    }
+
+    internal enum QUIC_TLS_PROTOCOL_VERSION
+    {
+        UNKNOWN = 0,
+        TLS_1_3 = 0x3000,
+    }
+
+    internal enum QUIC_CIPHER_ALGORITHM
+    {
+        NONE = 0,
+        AES_128 = 0x660E,
+        AES_256 = 0x6610,
+        CHACHA20 = 0x6612,
+    }
+
+    internal enum QUIC_HASH_ALGORITHM
+    {
+        NONE = 0,
+        SHA_256 = 0x800C,
+        SHA_384 = 0x800D,
+    }
+
+    internal enum QUIC_KEY_EXCHANGE_ALGORITHM
+    {
+        NONE = 0,
+    }
+
+    internal enum QUIC_CIPHER_SUITE
+    {
+        TLS_AES_128_GCM_SHA256 = 0x1301,
+        TLS_AES_256_GCM_SHA384 = 0x1302,
+        TLS_CHACHA20_POLY1305_SHA256 = 0x1303,
+    }
+
+    internal enum QUIC_CONGESTION_CONTROL_ALGORITHM
+    {
+        CUBIC,
+        MAX,
+    }
+
+    internal partial struct QUIC_HANDSHAKE_INFO
+    {
+        internal QUIC_TLS_PROTOCOL_VERSION TlsProtocolVersion;
+
+        internal QUIC_CIPHER_ALGORITHM CipherAlgorithm;
+
+        [NativeTypeName("int32_t")]
+        internal int CipherStrength;
+
+        internal QUIC_HASH_ALGORITHM Hash;
+
+        [NativeTypeName("int32_t")]
+        internal int HashStrength;
+
+        internal QUIC_KEY_EXCHANGE_ALGORITHM KeyExchangeAlgorithm;
+
+        [NativeTypeName("int32_t")]
+        internal int KeyExchangeStrength;
+
+        internal QUIC_CIPHER_SUITE CipherSuite;
+    }
+
+    internal partial struct QUIC_STATISTICS
+    {
+        [NativeTypeName("uint64_t")]
+        internal ulong CorrelationId;
+
+        internal uint _bitfield;
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint VersionNegotiation
+        {
+            get
+            {
+                return _bitfield & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~0x1u) | (value & 0x1u);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint StatelessRetry
+        {
+            get
+            {
+                return (_bitfield >> 1) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint ResumptionAttempted
+        {
+            get
+            {
+                return (_bitfield >> 2) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 2)) | ((value & 0x1u) << 2);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint ResumptionSucceeded
+        {
+            get
+            {
+                return (_bitfield >> 3) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 3)) | ((value & 0x1u) << 3);
+            }
+        }
+
+        [NativeTypeName("uint32_t")]
+        internal uint Rtt;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MinRtt;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MaxRtt;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _Timing_e__Struct Timing;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _Handshake_e__Struct Handshake;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _Send_e__Struct Send;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _Recv_e__Struct Recv;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _Misc_e__Struct Misc;
+
+        internal partial struct _Timing_e__Struct
+        {
+            [NativeTypeName("uint64_t")]
+            internal ulong Start;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong InitialFlightEnd;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong HandshakeFlightEnd;
+        }
+
+        internal partial struct _Handshake_e__Struct
+        {
+            [NativeTypeName("uint32_t")]
+            internal uint ClientFlight1Bytes;
+
+            [NativeTypeName("uint32_t")]
+            internal uint ServerFlight1Bytes;
+
+            [NativeTypeName("uint32_t")]
+            internal uint ClientFlight2Bytes;
+        }
+
+        internal partial struct _Send_e__Struct
+        {
+            [NativeTypeName("uint16_t")]
+            internal ushort PathMtu;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong RetransmittablePackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong SuspectedLostPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong SpuriousLostPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalBytes;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalStreamBytes;
+
+            [NativeTypeName("uint32_t")]
+            internal uint CongestionCount;
+
+            [NativeTypeName("uint32_t")]
+            internal uint PersistentCongestionCount;
+        }
+
+        internal partial struct _Recv_e__Struct
+        {
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong ReorderedPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong DroppedPackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong DuplicatePackets;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalBytes;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong TotalStreamBytes;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong DecryptionFailures;
+
+            [NativeTypeName("uint64_t")]
+            internal ulong ValidAckFrames;
+        }
+
+        internal partial struct _Misc_e__Struct
+        {
+            [NativeTypeName("uint32_t")]
+            internal uint KeyUpdateCount;
+        }
+    }
+
+    internal partial struct QUIC_STATISTICS_V2
+    {
+        [NativeTypeName("uint64_t")]
+        internal ulong CorrelationId;
+
+        internal uint _bitfield;
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint VersionNegotiation
+        {
+            get
+            {
+                return _bitfield & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~0x1u) | (value & 0x1u);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint StatelessRetry
+        {
+            get
+            {
+                return (_bitfield >> 1) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint ResumptionAttempted
+        {
+            get
+            {
+                return (_bitfield >> 2) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 2)) | ((value & 0x1u) << 2);
+            }
+        }
+
+        [NativeTypeName("uint32_t : 1")]
+        internal uint ResumptionSucceeded
+        {
+            get
+            {
+                return (_bitfield >> 3) & 0x1u;
+            }
+
+            set
+            {
+                _bitfield = (_bitfield & ~(0x1u << 3)) | ((value & 0x1u) << 3);
+            }
+        }
+
+        [NativeTypeName("uint32_t")]
+        internal uint Rtt;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MinRtt;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MaxRtt;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong TimingStart;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong TimingInitialFlightEnd;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong TimingHandshakeFlightEnd;
+
+        [NativeTypeName("uint32_t")]
+        internal uint HandshakeClientFlight1Bytes;
+
+        [NativeTypeName("uint32_t")]
+        internal uint HandshakeServerFlight1Bytes;
+
+        [NativeTypeName("uint32_t")]
+        internal uint HandshakeClientFlight2Bytes;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort SendPathMtu;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendTotalPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendRetransmittablePackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendSuspectedLostPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendSpuriousLostPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendTotalBytes;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong SendTotalStreamBytes;
+
+        [NativeTypeName("uint32_t")]
+        internal uint SendCongestionCount;
+
+        [NativeTypeName("uint32_t")]
+        internal uint SendPersistentCongestionCount;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvTotalPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvReorderedPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvDroppedPackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvDuplicatePackets;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvTotalBytes;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvTotalStreamBytes;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvDecryptionFailures;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong RecvValidAckFrames;
+
+        [NativeTypeName("uint32_t")]
+        internal uint KeyUpdateCount;
+
+        [NativeTypeName("uint32_t")]
+        internal uint SendCongestionWindow;
+    }
+
+    internal partial struct QUIC_LISTENER_STATISTICS
+    {
+        [NativeTypeName("uint64_t")]
+        internal ulong TotalAcceptedConnections;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong TotalRejectedConnections;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong BindingRecvDroppedPackets;
+    }
+
+    internal enum QUIC_PERFORMANCE_COUNTERS
+    {
+        CONN_CREATED,
+        CONN_HANDSHAKE_FAIL,
+        CONN_APP_REJECT,
+        CONN_RESUMED,
+        CONN_ACTIVE,
+        CONN_CONNECTED,
+        CONN_PROTOCOL_ERRORS,
+        CONN_NO_ALPN,
+        STRM_ACTIVE,
+        PKTS_SUSPECTED_LOST,
+        PKTS_DROPPED,
+        PKTS_DECRYPTION_FAIL,
+        UDP_RECV,
+        UDP_SEND,
+        UDP_RECV_BYTES,
+        UDP_SEND_BYTES,
+        UDP_RECV_EVENTS,
+        UDP_SEND_CALLS,
+        APP_SEND_BYTES,
+        APP_RECV_BYTES,
+        CONN_QUEUE_DEPTH,
+        CONN_OPER_QUEUE_DEPTH,
+        CONN_OPER_QUEUED,
+        CONN_OPER_COMPLETED,
+        WORK_OPER_QUEUE_DEPTH,
+        WORK_OPER_QUEUED,
+        WORK_OPER_COMPLETED,
+        PATH_VALIDATED,
+        PATH_FAILURE,
+        SEND_STATELESS_RESET,
+        SEND_STATELESS_RETRY,
+        MAX,
+    }
+
+    internal unsafe partial struct QUIC_VERSION_SETTINGS
+    {
+        [NativeTypeName("uint32_t *")]
+        internal uint* AcceptableVersions;
+
+        [NativeTypeName("uint32_t *")]
+        internal uint* OfferedVersions;
+
+        [NativeTypeName("uint32_t *")]
+        internal uint* FullyDeployedVersions;
+
+        [NativeTypeName("uint32_t")]
+        internal uint AcceptableVersionsLength;
+
+        [NativeTypeName("uint32_t")]
+        internal uint OfferedVersionsLength;
+
+        [NativeTypeName("uint32_t")]
+        internal uint FullyDeployedVersionsLength;
+    }
+
+    internal partial struct QUIC_GLOBAL_SETTINGS
+    {
+        [NativeTypeName("QUIC_GLOBAL_SETTINGS::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort RetryMemoryLimit;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort LoadBalancingMode;
+
+        internal ref ulong IsSetFlags
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IsSetFlags, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._IsSet_e__Struct IsSet
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IsSet, 1));
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            [NativeTypeName("uint64_t")]
+            internal ulong IsSetFlags;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _IsSet_e__Struct IsSet;
+
+            internal partial struct _IsSet_e__Struct
+            {
+                internal ulong _bitfield;
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong RetryMemoryLimit
+                {
+                    get
+                    {
+                        return _bitfield & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~0x1UL) | (value & 0x1UL);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong LoadBalancingMode
+                {
+                    get
+                    {
+                        return (_bitfield >> 1) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 1)) | ((value & 0x1UL) << 1);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 62")]
+                internal ulong RESERVED
+                {
+                    get
+                    {
+                        return (_bitfield >> 2) & 0x3FFFFFFFUL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x3FFFFFFFUL << 2)) | ((value & 0x3FFFFFFFUL) << 2);
+                    }
+                }
+            }
+        }
+    }
+
+    internal partial struct QUIC_SETTINGS
+    {
+        [NativeTypeName("QUIC_SETTINGS::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong MaxBytesPerKey;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong HandshakeIdleTimeoutMs;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong IdleTimeoutMs;
+
+        [NativeTypeName("uint64_t")]
+        internal ulong MtuDiscoverySearchCompleteTimeoutUs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint TlsClientMaxSendBuffer;
+
+        [NativeTypeName("uint32_t")]
+        internal uint TlsServerMaxSendBuffer;
+
+        [NativeTypeName("uint32_t")]
+        internal uint StreamRecvWindowDefault;
+
+        [NativeTypeName("uint32_t")]
+        internal uint StreamRecvBufferDefault;
+
+        [NativeTypeName("uint32_t")]
+        internal uint ConnFlowControlWindow;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MaxWorkerQueueDelayUs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MaxStatelessOperations;
+
+        [NativeTypeName("uint32_t")]
+        internal uint InitialWindowPackets;
+
+        [NativeTypeName("uint32_t")]
+        internal uint SendIdleTimeoutMs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint InitialRttMs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint MaxAckDelayMs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint DisconnectTimeoutMs;
+
+        [NativeTypeName("uint32_t")]
+        internal uint KeepAliveIntervalMs;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort CongestionControlAlgorithm;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort PeerBidiStreamCount;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort PeerUnidiStreamCount;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort MaxBindingStatelessOperations;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort StatelessOperationExpirationMs;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort MinimumMtu;
+
+        [NativeTypeName("uint16_t")]
+        internal ushort MaximumMtu;
+
+        internal byte _bitfield;
+
+        [NativeTypeName("uint8_t : 1")]
+        internal byte SendBufferingEnabled
+        {
+            get
+            {
+                return (byte)(_bitfield & 0x1u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+            }
+        }
+
+        [NativeTypeName("uint8_t : 1")]
+        internal byte PacingEnabled
+        {
+            get
+            {
+                return (byte)((_bitfield >> 1) & 0x1u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1));
+            }
+        }
+
+        [NativeTypeName("uint8_t : 1")]
+        internal byte MigrationEnabled
+        {
+            get
+            {
+                return (byte)((_bitfield >> 2) & 0x1u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~(0x1u << 2)) | ((value & 0x1u) << 2));
+            }
+        }
+
+        [NativeTypeName("uint8_t : 1")]
+        internal byte DatagramReceiveEnabled
+        {
+            get
+            {
+                return (byte)((_bitfield >> 3) & 0x1u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~(0x1u << 3)) | ((value & 0x1u) << 3));
+            }
+        }
+
+        [NativeTypeName("uint8_t : 2")]
+        internal byte ServerResumptionLevel
+        {
+            get
+            {
+                return (byte)((_bitfield >> 4) & 0x3u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~(0x3u << 4)) | ((value & 0x3u) << 4));
+            }
+        }
+
+        [NativeTypeName("uint8_t : 2")]
+        internal byte RESERVED
+        {
+            get
+            {
+                return (byte)((_bitfield >> 6) & 0x3u);
+            }
+
+            set
+            {
+                _bitfield = (byte)((_bitfield & ~(0x3u << 6)) | ((value & 0x3u) << 6));
+            }
+        }
+
+        [NativeTypeName("uint8_t")]
+        internal byte MaxOperationsPerDrain;
+
+        [NativeTypeName("uint8_t")]
+        internal byte MtuDiscoveryMissingProbeCount;
+
+        internal ref ulong IsSetFlags
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IsSetFlags, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._IsSet_e__Struct IsSet
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IsSet, 1));
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            [NativeTypeName("uint64_t")]
+            internal ulong IsSetFlags;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _IsSet_e__Struct IsSet;
+
+            internal partial struct _IsSet_e__Struct
+            {
+                internal ulong _bitfield;
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxBytesPerKey
+                {
+                    get
+                    {
+                        return _bitfield & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~0x1UL) | (value & 0x1UL);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong HandshakeIdleTimeoutMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 1) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 1)) | ((value & 0x1UL) << 1);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong IdleTimeoutMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 2) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 2)) | ((value & 0x1UL) << 2);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MtuDiscoverySearchCompleteTimeoutUs
+                {
+                    get
+                    {
+                        return (_bitfield >> 3) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 3)) | ((value & 0x1UL) << 3);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong TlsClientMaxSendBuffer
+                {
+                    get
+                    {
+                        return (_bitfield >> 4) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 4)) | ((value & 0x1UL) << 4);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong TlsServerMaxSendBuffer
+                {
+                    get
+                    {
+                        return (_bitfield >> 5) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 5)) | ((value & 0x1UL) << 5);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong StreamRecvWindowDefault
+                {
+                    get
+                    {
+                        return (_bitfield >> 6) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 6)) | ((value & 0x1UL) << 6);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong StreamRecvBufferDefault
+                {
+                    get
+                    {
+                        return (_bitfield >> 7) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 7)) | ((value & 0x1UL) << 7);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong ConnFlowControlWindow
+                {
+                    get
+                    {
+                        return (_bitfield >> 8) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 8)) | ((value & 0x1UL) << 8);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxWorkerQueueDelayUs
+                {
+                    get
+                    {
+                        return (_bitfield >> 9) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 9)) | ((value & 0x1UL) << 9);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxStatelessOperations
+                {
+                    get
+                    {
+                        return (_bitfield >> 10) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 10)) | ((value & 0x1UL) << 10);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong InitialWindowPackets
+                {
+                    get
+                    {
+                        return (_bitfield >> 11) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 11)) | ((value & 0x1UL) << 11);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong SendIdleTimeoutMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 12) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 12)) | ((value & 0x1UL) << 12);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong InitialRttMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 13) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 13)) | ((value & 0x1UL) << 13);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxAckDelayMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 14) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 14)) | ((value & 0x1UL) << 14);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong DisconnectTimeoutMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 15) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 15)) | ((value & 0x1UL) << 15);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong KeepAliveIntervalMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 16) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 16)) | ((value & 0x1UL) << 16);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong CongestionControlAlgorithm
+                {
+                    get
+                    {
+                        return (_bitfield >> 17) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 17)) | ((value & 0x1UL) << 17);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong PeerBidiStreamCount
+                {
+                    get
+                    {
+                        return (_bitfield >> 18) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 18)) | ((value & 0x1UL) << 18);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong PeerUnidiStreamCount
+                {
+                    get
+                    {
+                        return (_bitfield >> 19) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 19)) | ((value & 0x1UL) << 19);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxBindingStatelessOperations
+                {
+                    get
+                    {
+                        return (_bitfield >> 20) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 20)) | ((value & 0x1UL) << 20);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong StatelessOperationExpirationMs
+                {
+                    get
+                    {
+                        return (_bitfield >> 21) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 21)) | ((value & 0x1UL) << 21);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MinimumMtu
+                {
+                    get
+                    {
+                        return (_bitfield >> 22) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 22)) | ((value & 0x1UL) << 22);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaximumMtu
+                {
+                    get
+                    {
+                        return (_bitfield >> 23) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 23)) | ((value & 0x1UL) << 23);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong SendBufferingEnabled
+                {
+                    get
+                    {
+                        return (_bitfield >> 24) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 24)) | ((value & 0x1UL) << 24);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong PacingEnabled
+                {
+                    get
+                    {
+                        return (_bitfield >> 25) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 25)) | ((value & 0x1UL) << 25);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MigrationEnabled
+                {
+                    get
+                    {
+                        return (_bitfield >> 26) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 26)) | ((value & 0x1UL) << 26);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong DatagramReceiveEnabled
+                {
+                    get
+                    {
+                        return (_bitfield >> 27) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 27)) | ((value & 0x1UL) << 27);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong ServerResumptionLevel
+                {
+                    get
+                    {
+                        return (_bitfield >> 28) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 28)) | ((value & 0x1UL) << 28);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MaxOperationsPerDrain
+                {
+                    get
+                    {
+                        return (_bitfield >> 29) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 29)) | ((value & 0x1UL) << 29);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 1")]
+                internal ulong MtuDiscoveryMissingProbeCount
+                {
+                    get
+                    {
+                        return (_bitfield >> 30) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 30)) | ((value & 0x1UL) << 30);
+                    }
+                }
+
+                [NativeTypeName("uint64_t : 33")]
+                internal ulong RESERVED
+                {
+                    get
+                    {
+                        return (_bitfield >> 31) & 0x1UL;
+                    }
+
+                    set
+                    {
+                        _bitfield = (_bitfield & ~(0x1UL << 31)) | ((value & 0x1UL) << 31);
+                    }
+                }
+            }
+        }
+    }
+
+    internal unsafe partial struct QUIC_TLS_SECRETS
+    {
+        [NativeTypeName("uint8_t")]
+        internal byte SecretLength;
+
+        [NativeTypeName("struct (anonymous struct)")]
+        internal _IsSet_e__Struct IsSet;
+
+        [NativeTypeName("uint8_t [32]")]
+        internal fixed byte ClientRandom[32];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte ClientEarlyTrafficSecret[64];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte ClientHandshakeTrafficSecret[64];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte ServerHandshakeTrafficSecret[64];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte ClientTrafficSecret0[64];
+
+        [NativeTypeName("uint8_t [64]")]
+        internal fixed byte ServerTrafficSecret0[64];
+
+        internal partial struct _IsSet_e__Struct
+        {
+            internal byte _bitfield;
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ClientRandom
+            {
+                get
+                {
+                    return (byte)(_bitfield & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+                }
+            }
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ClientEarlyTrafficSecret
+            {
+                get
+                {
+                    return (byte)((_bitfield >> 1) & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1));
+                }
+            }
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ClientHandshakeTrafficSecret
+            {
+                get
+                {
+                    return (byte)((_bitfield >> 2) & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~(0x1u << 2)) | ((value & 0x1u) << 2));
+                }
+            }
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ServerHandshakeTrafficSecret
+            {
+                get
+                {
+                    return (byte)((_bitfield >> 3) & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~(0x1u << 3)) | ((value & 0x1u) << 3));
+                }
+            }
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ClientTrafficSecret0
+            {
+                get
+                {
+                    return (byte)((_bitfield >> 4) & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~(0x1u << 4)) | ((value & 0x1u) << 4));
+                }
+            }
+
+            [NativeTypeName("uint8_t : 1")]
+            internal byte ServerTrafficSecret0
+            {
+                get
+                {
+                    return (byte)((_bitfield >> 5) & 0x1u);
+                }
+
+                set
+                {
+                    _bitfield = (byte)((_bitfield & ~(0x1u << 5)) | ((value & 0x1u) << 5));
+                }
+            }
+        }
+    }
+
+    internal unsafe partial struct QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W
+    {
+        [NativeTypeName("unsigned long")]
+        internal uint Attribute;
+
+        internal void* Buffer;
+    }
+
+    internal enum QUIC_LISTENER_EVENT_TYPE
+    {
+        NEW_CONNECTION = 0,
+        STOP_COMPLETE = 1,
+    }
+
+    internal partial struct QUIC_LISTENER_EVENT
+    {
+        internal QUIC_LISTENER_EVENT_TYPE Type;
+
+        [NativeTypeName("QUIC_LISTENER_EVENT::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        internal ref _Anonymous_e__Union._NEW_CONNECTION_e__Struct NEW_CONNECTION
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.NEW_CONNECTION, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._STOP_COMPLETE_e__Struct STOP_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.STOP_COMPLETE, 1));
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _NEW_CONNECTION_e__Struct NEW_CONNECTION;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _STOP_COMPLETE_e__Struct STOP_COMPLETE;
+
+            internal unsafe partial struct _NEW_CONNECTION_e__Struct
+            {
+                [NativeTypeName("const QUIC_NEW_CONNECTION_INFO *")]
+                internal QUIC_NEW_CONNECTION_INFO* Info;
+
+                [NativeTypeName("HQUIC")]
+                internal QUIC_HANDLE* Connection;
+            }
+
+            internal partial struct _STOP_COMPLETE_e__Struct
+            {
+                internal byte _bitfield;
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte AppCloseInProgress
+                {
+                    get
+                    {
+                        return (byte)(_bitfield & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+                    }
+                }
+
+                [NativeTypeName("BOOLEAN : 7")]
+                internal byte RESERVED
+                {
+                    get
+                    {
+                        return (byte)((_bitfield >> 1) & 0x7Fu);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~(0x7Fu << 1)) | ((value & 0x7Fu) << 1));
+                    }
+                }
+            }
+        }
+    }
+
+    internal enum QUIC_CONNECTION_EVENT_TYPE
+    {
+        CONNECTED = 0,
+        SHUTDOWN_INITIATED_BY_TRANSPORT = 1,
+        SHUTDOWN_INITIATED_BY_PEER = 2,
+        SHUTDOWN_COMPLETE = 3,
+        LOCAL_ADDRESS_CHANGED = 4,
+        PEER_ADDRESS_CHANGED = 5,
+        PEER_STREAM_STARTED = 6,
+        STREAMS_AVAILABLE = 7,
+        PEER_NEEDS_STREAMS = 8,
+        IDEAL_PROCESSOR_CHANGED = 9,
+        DATAGRAM_STATE_CHANGED = 10,
+        DATAGRAM_RECEIVED = 11,
+        DATAGRAM_SEND_STATE_CHANGED = 12,
+        RESUMED = 13,
+        RESUMPTION_TICKET_RECEIVED = 14,
+        PEER_CERTIFICATE_RECEIVED = 15,
+    }
+
+    internal partial struct QUIC_CONNECTION_EVENT
+    {
+        internal QUIC_CONNECTION_EVENT_TYPE Type;
+
+        [NativeTypeName("QUIC_CONNECTION_EVENT::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        internal ref _Anonymous_e__Union._CONNECTED_e__Struct CONNECTED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.CONNECTED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SHUTDOWN_INITIATED_BY_TRANSPORT_e__Struct SHUTDOWN_INITIATED_BY_TRANSPORT
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SHUTDOWN_INITIATED_BY_TRANSPORT, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SHUTDOWN_INITIATED_BY_PEER_e__Struct SHUTDOWN_INITIATED_BY_PEER
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SHUTDOWN_INITIATED_BY_PEER, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SHUTDOWN_COMPLETE_e__Struct SHUTDOWN_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SHUTDOWN_COMPLETE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._LOCAL_ADDRESS_CHANGED_e__Struct LOCAL_ADDRESS_CHANGED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.LOCAL_ADDRESS_CHANGED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._PEER_ADDRESS_CHANGED_e__Struct PEER_ADDRESS_CHANGED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.PEER_ADDRESS_CHANGED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._PEER_STREAM_STARTED_e__Struct PEER_STREAM_STARTED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.PEER_STREAM_STARTED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._STREAMS_AVAILABLE_e__Struct STREAMS_AVAILABLE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.STREAMS_AVAILABLE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._IDEAL_PROCESSOR_CHANGED_e__Struct IDEAL_PROCESSOR_CHANGED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IDEAL_PROCESSOR_CHANGED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._DATAGRAM_STATE_CHANGED_e__Struct DATAGRAM_STATE_CHANGED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.DATAGRAM_STATE_CHANGED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._DATAGRAM_RECEIVED_e__Struct DATAGRAM_RECEIVED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.DATAGRAM_RECEIVED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._DATAGRAM_SEND_STATE_CHANGED_e__Struct DATAGRAM_SEND_STATE_CHANGED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.DATAGRAM_SEND_STATE_CHANGED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._RESUMED_e__Struct RESUMED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.RESUMED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._RESUMPTION_TICKET_RECEIVED_e__Struct RESUMPTION_TICKET_RECEIVED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.RESUMPTION_TICKET_RECEIVED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._PEER_CERTIFICATE_RECEIVED_e__Struct PEER_CERTIFICATE_RECEIVED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.PEER_CERTIFICATE_RECEIVED, 1));
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _CONNECTED_e__Struct CONNECTED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SHUTDOWN_INITIATED_BY_TRANSPORT_e__Struct SHUTDOWN_INITIATED_BY_TRANSPORT;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SHUTDOWN_INITIATED_BY_PEER_e__Struct SHUTDOWN_INITIATED_BY_PEER;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SHUTDOWN_COMPLETE_e__Struct SHUTDOWN_COMPLETE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _LOCAL_ADDRESS_CHANGED_e__Struct LOCAL_ADDRESS_CHANGED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _PEER_ADDRESS_CHANGED_e__Struct PEER_ADDRESS_CHANGED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _PEER_STREAM_STARTED_e__Struct PEER_STREAM_STARTED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _STREAMS_AVAILABLE_e__Struct STREAMS_AVAILABLE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _IDEAL_PROCESSOR_CHANGED_e__Struct IDEAL_PROCESSOR_CHANGED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _DATAGRAM_STATE_CHANGED_e__Struct DATAGRAM_STATE_CHANGED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _DATAGRAM_RECEIVED_e__Struct DATAGRAM_RECEIVED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _DATAGRAM_SEND_STATE_CHANGED_e__Struct DATAGRAM_SEND_STATE_CHANGED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _RESUMED_e__Struct RESUMED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _RESUMPTION_TICKET_RECEIVED_e__Struct RESUMPTION_TICKET_RECEIVED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _PEER_CERTIFICATE_RECEIVED_e__Struct PEER_CERTIFICATE_RECEIVED;
+
+            internal unsafe partial struct _CONNECTED_e__Struct
+            {
+                [NativeTypeName("BOOLEAN")]
+                internal byte SessionResumed;
+
+                [NativeTypeName("uint8_t")]
+                internal byte NegotiatedAlpnLength;
+
+                [NativeTypeName("const uint8_t *")]
+                internal byte* NegotiatedAlpn;
+            }
+
+            internal partial struct _SHUTDOWN_INITIATED_BY_TRANSPORT_e__Struct
+            {
+                [NativeTypeName("HRESULT")]
+                internal int Status;
+            }
+
+            internal partial struct _SHUTDOWN_INITIATED_BY_PEER_e__Struct
+            {
+                [NativeTypeName("QUIC_UINT62")]
+                internal ulong ErrorCode;
+            }
+
+            internal partial struct _SHUTDOWN_COMPLETE_e__Struct
+            {
+                internal byte _bitfield;
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte HandshakeCompleted
+                {
+                    get
+                    {
+                        return (byte)(_bitfield & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+                    }
+                }
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte PeerAcknowledgedShutdown
+                {
+                    get
+                    {
+                        return (byte)((_bitfield >> 1) & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1));
+                    }
+                }
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte AppCloseInProgress
+                {
+                    get
+                    {
+                        return (byte)((_bitfield >> 2) & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~(0x1u << 2)) | ((value & 0x1u) << 2));
+                    }
+                }
+            }
+
+            internal unsafe partial struct _LOCAL_ADDRESS_CHANGED_e__Struct
+            {
+                [NativeTypeName("const QUIC_ADDR *")]
+                internal QuicAddr* Address;
+            }
+
+            internal unsafe partial struct _PEER_ADDRESS_CHANGED_e__Struct
+            {
+                [NativeTypeName("const QUIC_ADDR *")]
+                internal QuicAddr* Address;
+            }
+
+            internal unsafe partial struct _PEER_STREAM_STARTED_e__Struct
+            {
+                [NativeTypeName("HQUIC")]
+                internal QUIC_HANDLE* Stream;
+
+                internal QUIC_STREAM_OPEN_FLAGS Flags;
+            }
+
+            internal partial struct _STREAMS_AVAILABLE_e__Struct
+            {
+                [NativeTypeName("uint16_t")]
+                internal ushort BidirectionalCount;
+
+                [NativeTypeName("uint16_t")]
+                internal ushort UnidirectionalCount;
+            }
+
+            internal partial struct _IDEAL_PROCESSOR_CHANGED_e__Struct
+            {
+                [NativeTypeName("uint16_t")]
+                internal ushort IdealProcessor;
+            }
+
+            internal partial struct _DATAGRAM_STATE_CHANGED_e__Struct
+            {
+                [NativeTypeName("BOOLEAN")]
+                internal byte SendEnabled;
+
+                [NativeTypeName("uint16_t")]
+                internal ushort MaxSendLength;
+            }
+
+            internal unsafe partial struct _DATAGRAM_RECEIVED_e__Struct
+            {
+                [NativeTypeName("const QUIC_BUFFER *")]
+                internal QUIC_BUFFER* Buffer;
+
+                internal QUIC_RECEIVE_FLAGS Flags;
+            }
+
+            internal unsafe partial struct _DATAGRAM_SEND_STATE_CHANGED_e__Struct
+            {
+                internal void* ClientContext;
+
+                internal QUIC_DATAGRAM_SEND_STATE State;
+            }
+
+            internal unsafe partial struct _RESUMED_e__Struct
+            {
+                [NativeTypeName("uint16_t")]
+                internal ushort ResumptionStateLength;
+
+                [NativeTypeName("const uint8_t *")]
+                internal byte* ResumptionState;
+            }
+
+            internal unsafe partial struct _RESUMPTION_TICKET_RECEIVED_e__Struct
+            {
+                [NativeTypeName("uint32_t")]
+                internal uint ResumptionTicketLength;
+
+                [NativeTypeName("const uint8_t *")]
+                internal byte* ResumptionTicket;
+            }
+
+            internal unsafe partial struct _PEER_CERTIFICATE_RECEIVED_e__Struct
+            {
+                [NativeTypeName("QUIC_CERTIFICATE *")]
+                internal void* Certificate;
+
+                [NativeTypeName("uint32_t")]
+                internal uint DeferredErrorFlags;
+
+                [NativeTypeName("HRESULT")]
+                internal int DeferredStatus;
+
+                [NativeTypeName("QUIC_CERTIFICATE_CHAIN *")]
+                internal void* Chain;
+            }
+        }
+    }
+
+    internal enum QUIC_STREAM_EVENT_TYPE
+    {
+        START_COMPLETE = 0,
+        RECEIVE = 1,
+        SEND_COMPLETE = 2,
+        PEER_SEND_SHUTDOWN = 3,
+        PEER_SEND_ABORTED = 4,
+        PEER_RECEIVE_ABORTED = 5,
+        SEND_SHUTDOWN_COMPLETE = 6,
+        SHUTDOWN_COMPLETE = 7,
+        IDEAL_SEND_BUFFER_SIZE = 8,
+        PEER_ACCEPTED = 9,
+    }
+
+    internal partial struct QUIC_STREAM_EVENT
+    {
+        internal QUIC_STREAM_EVENT_TYPE Type;
+
+        [NativeTypeName("QUIC_STREAM_EVENT::(anonymous union)")]
+        internal _Anonymous_e__Union Anonymous;
+
+        internal ref _Anonymous_e__Union._START_COMPLETE_e__Struct START_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.START_COMPLETE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._RECEIVE_e__Struct RECEIVE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.RECEIVE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SEND_COMPLETE_e__Struct SEND_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SEND_COMPLETE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._PEER_SEND_ABORTED_e__Struct PEER_SEND_ABORTED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.PEER_SEND_ABORTED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._PEER_RECEIVE_ABORTED_e__Struct PEER_RECEIVE_ABORTED
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.PEER_RECEIVE_ABORTED, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SEND_SHUTDOWN_COMPLETE_e__Struct SEND_SHUTDOWN_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SEND_SHUTDOWN_COMPLETE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._SHUTDOWN_COMPLETE_e__Struct SHUTDOWN_COMPLETE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.SHUTDOWN_COMPLETE, 1));
+            }
+        }
+
+        internal ref _Anonymous_e__Union._IDEAL_SEND_BUFFER_SIZE_e__Struct IDEAL_SEND_BUFFER_SIZE
+        {
+            get
+            {
+                return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.IDEAL_SEND_BUFFER_SIZE, 1));
+            }
+        }
+
+        [StructLayout(LayoutKind.Explicit)]
+        internal partial struct _Anonymous_e__Union
+        {
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _START_COMPLETE_e__Struct START_COMPLETE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _RECEIVE_e__Struct RECEIVE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SEND_COMPLETE_e__Struct SEND_COMPLETE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _PEER_SEND_ABORTED_e__Struct PEER_SEND_ABORTED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _PEER_RECEIVE_ABORTED_e__Struct PEER_RECEIVE_ABORTED;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SEND_SHUTDOWN_COMPLETE_e__Struct SEND_SHUTDOWN_COMPLETE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _SHUTDOWN_COMPLETE_e__Struct SHUTDOWN_COMPLETE;
+
+            [FieldOffset(0)]
+            [NativeTypeName("struct (anonymous struct)")]
+            internal _IDEAL_SEND_BUFFER_SIZE_e__Struct IDEAL_SEND_BUFFER_SIZE;
+
+            internal partial struct _START_COMPLETE_e__Struct
+            {
+                [NativeTypeName("HRESULT")]
+                internal int Status;
+
+                [NativeTypeName("QUIC_UINT62")]
+                internal ulong ID;
+
+                internal byte _bitfield;
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte PeerAccepted
+                {
+                    get
+                    {
+                        return (byte)(_bitfield & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+                    }
+                }
+
+                [NativeTypeName("BOOLEAN : 7")]
+                internal byte RESERVED
+                {
+                    get
+                    {
+                        return (byte)((_bitfield >> 1) & 0x7Fu);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~(0x7Fu << 1)) | ((value & 0x7Fu) << 1));
+                    }
+                }
+            }
+
+            internal unsafe partial struct _RECEIVE_e__Struct
+            {
+                [NativeTypeName("uint64_t")]
+                internal ulong AbsoluteOffset;
+
+                [NativeTypeName("uint64_t")]
+                internal ulong TotalBufferLength;
+
+                [NativeTypeName("const QUIC_BUFFER *")]
+                internal QUIC_BUFFER* Buffers;
+
+                [NativeTypeName("uint32_t")]
+                internal uint BufferCount;
+
+                internal QUIC_RECEIVE_FLAGS Flags;
+            }
+
+            internal unsafe partial struct _SEND_COMPLETE_e__Struct
+            {
+                [NativeTypeName("BOOLEAN")]
+                internal byte Canceled;
+
+                internal void* ClientContext;
+            }
+
+            internal partial struct _PEER_SEND_ABORTED_e__Struct
+            {
+                [NativeTypeName("QUIC_UINT62")]
+                internal ulong ErrorCode;
+            }
+
+            internal partial struct _PEER_RECEIVE_ABORTED_e__Struct
+            {
+                [NativeTypeName("QUIC_UINT62")]
+                internal ulong ErrorCode;
+            }
+
+            internal partial struct _SEND_SHUTDOWN_COMPLETE_e__Struct
+            {
+                [NativeTypeName("BOOLEAN")]
+                internal byte Graceful;
+            }
+
+            internal partial struct _SHUTDOWN_COMPLETE_e__Struct
+            {
+                [NativeTypeName("BOOLEAN")]
+                internal byte ConnectionShutdown;
+
+                internal byte _bitfield;
+
+                [NativeTypeName("BOOLEAN : 1")]
+                internal byte AppCloseInProgress
+                {
+                    get
+                    {
+                        return (byte)(_bitfield & 0x1u);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~0x1u) | (value & 0x1u));
+                    }
+                }
+
+                [NativeTypeName("BOOLEAN : 7")]
+                internal byte RESERVED
+                {
+                    get
+                    {
+                        return (byte)((_bitfield >> 1) & 0x7Fu);
+                    }
+
+                    set
+                    {
+                        _bitfield = (byte)((_bitfield & ~(0x7Fu << 1)) | ((value & 0x7Fu) << 1));
+                    }
+                }
+            }
+
+            internal partial struct _IDEAL_SEND_BUFFER_SIZE_e__Struct
+            {
+                [NativeTypeName("uint64_t")]
+                internal ulong ByteCount;
+            }
+        }
+    }
+
+    internal unsafe partial struct QUIC_API_TABLE
+    {
+        [NativeTypeName("QUIC_SET_CONTEXT_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, void> SetContext;
+
+        [NativeTypeName("QUIC_GET_CONTEXT_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*> GetContext;
+
+        [NativeTypeName("QUIC_SET_CALLBACK_HANDLER_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, void*, void> SetCallbackHandler;
+
+        [NativeTypeName("QUIC_SET_PARAM_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, uint, uint, void*, int> SetParam;
+
+        [NativeTypeName("QUIC_GET_PARAM_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, uint, uint*, void*, int> GetParam;
+
+        [NativeTypeName("QUIC_REGISTRATION_OPEN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_REGISTRATION_CONFIG*, QUIC_HANDLE**, int> RegistrationOpen;
+
+        [NativeTypeName("QUIC_REGISTRATION_CLOSE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> RegistrationClose;
+
+        [NativeTypeName("QUIC_REGISTRATION_SHUTDOWN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_CONNECTION_SHUTDOWN_FLAGS, ulong, void> RegistrationShutdown;
+
+        [NativeTypeName("QUIC_CONFIGURATION_OPEN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_BUFFER*, uint, QUIC_SETTINGS*, uint, void*, QUIC_HANDLE**, int> ConfigurationOpen;
+
+        [NativeTypeName("QUIC_CONFIGURATION_CLOSE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> ConfigurationClose;
+
+        [NativeTypeName("QUIC_CONFIGURATION_LOAD_CREDENTIAL_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_CREDENTIAL_CONFIG*, int> ConfigurationLoadCredential;
+
+        [NativeTypeName("QUIC_LISTENER_OPEN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, QUIC_LISTENER_EVENT*, int>, void*, QUIC_HANDLE**, int> ListenerOpen;
+
+        [NativeTypeName("QUIC_LISTENER_CLOSE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> ListenerClose;
+
+        [NativeTypeName("QUIC_LISTENER_START_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_BUFFER*, uint, QuicAddr*, int> ListenerStart;
+
+        [NativeTypeName("QUIC_LISTENER_STOP_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> ListenerStop;
+
+        [NativeTypeName("QUIC_CONNECTION_OPEN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, QUIC_CONNECTION_EVENT*, int>, void*, QUIC_HANDLE**, int> ConnectionOpen;
+
+        [NativeTypeName("QUIC_CONNECTION_CLOSE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> ConnectionClose;
+
+        [NativeTypeName("QUIC_CONNECTION_SHUTDOWN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_CONNECTION_SHUTDOWN_FLAGS, ulong, void> ConnectionShutdown;
+
+        [NativeTypeName("QUIC_CONNECTION_START_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_HANDLE*, ushort, sbyte*, ushort, int> ConnectionStart;
+
+        [NativeTypeName("QUIC_CONNECTION_SET_CONFIGURATION_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_HANDLE*, int> ConnectionSetConfiguration;
+
+        [NativeTypeName("QUIC_CONNECTION_SEND_RESUMPTION_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_SEND_RESUMPTION_FLAGS, ushort, byte*, int> ConnectionSendResumptionTicket;
+
+        [NativeTypeName("QUIC_STREAM_OPEN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_STREAM_OPEN_FLAGS, delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, QUIC_STREAM_EVENT*, int>, void*, QUIC_HANDLE**, int> StreamOpen;
+
+        [NativeTypeName("QUIC_STREAM_CLOSE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void> StreamClose;
+
+        [NativeTypeName("QUIC_STREAM_START_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_STREAM_START_FLAGS, int> StreamStart;
+
+        [NativeTypeName("QUIC_STREAM_SHUTDOWN_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_STREAM_SHUTDOWN_FLAGS, ulong, int> StreamShutdown;
+
+        [NativeTypeName("QUIC_STREAM_SEND_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_BUFFER*, uint, QUIC_SEND_FLAGS, void*, int> StreamSend;
+
+        [NativeTypeName("QUIC_STREAM_RECEIVE_COMPLETE_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, ulong, void> StreamReceiveComplete;
+
+        [NativeTypeName("QUIC_STREAM_RECEIVE_SET_ENABLED_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, byte, int> StreamReceiveSetEnabled;
+
+        [NativeTypeName("QUIC_DATAGRAM_SEND_FN")]
+        internal delegate* unmanaged[Cdecl]<QUIC_HANDLE*, QUIC_BUFFER*, uint, QUIC_SEND_FLAGS, void*, int> DatagramSend;
+    }
+
+    internal static unsafe partial class MsQuic
+    {
+        [DllImport("msquic", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+        [return: NativeTypeName("HRESULT")]
+        internal static extern int MsQuicOpenVersion([NativeTypeName("uint32_t")] uint Version, [NativeTypeName("const void **")] void** QuicApi);
+
+        [DllImport("msquic", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
+        internal static extern void MsQuicClose([NativeTypeName("const void *")] void* QuicApi);
+
+        [NativeTypeName("#define QUIC_MAX_ALPN_LENGTH 255")]
+        internal const uint QUIC_MAX_ALPN_LENGTH = 255;
+
+        [NativeTypeName("#define QUIC_MAX_SNI_LENGTH 65535")]
+        internal const uint QUIC_MAX_SNI_LENGTH = 65535;
+
+        [NativeTypeName("#define QUIC_MAX_RESUMPTION_APP_DATA_LENGTH 1000")]
+        internal const uint QUIC_MAX_RESUMPTION_APP_DATA_LENGTH = 1000;
+
+        [NativeTypeName("#define QUIC_MAX_TICKET_KEY_COUNT 16")]
+        internal const uint QUIC_MAX_TICKET_KEY_COUNT = 16;
+
+        [NativeTypeName("#define QUIC_TLS_SECRETS_MAX_SECRET_LEN 64")]
+        internal const uint QUIC_TLS_SECRETS_MAX_SECRET_LEN = 64;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_GLOBAL 0x01000000")]
+        internal const uint QUIC_PARAM_PREFIX_GLOBAL = 0x01000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_REGISTRATION 0x02000000")]
+        internal const uint QUIC_PARAM_PREFIX_REGISTRATION = 0x02000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_CONFIGURATION 0x03000000")]
+        internal const uint QUIC_PARAM_PREFIX_CONFIGURATION = 0x03000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_LISTENER 0x04000000")]
+        internal const uint QUIC_PARAM_PREFIX_LISTENER = 0x04000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_CONNECTION 0x05000000")]
+        internal const uint QUIC_PARAM_PREFIX_CONNECTION = 0x05000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_TLS 0x06000000")]
+        internal const uint QUIC_PARAM_PREFIX_TLS = 0x06000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_TLS_SCHANNEL 0x07000000")]
+        internal const uint QUIC_PARAM_PREFIX_TLS_SCHANNEL = 0x07000000;
+
+        [NativeTypeName("#define QUIC_PARAM_PREFIX_STREAM 0x08000000")]
+        internal const uint QUIC_PARAM_PREFIX_STREAM = 0x08000000;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_RETRY_MEMORY_PERCENT 0x01000000")]
+        internal const uint QUIC_PARAM_GLOBAL_RETRY_MEMORY_PERCENT = 0x01000000;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_SUPPORTED_VERSIONS 0x01000001")]
+        internal const uint QUIC_PARAM_GLOBAL_SUPPORTED_VERSIONS = 0x01000001;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE 0x01000002")]
+        internal const uint QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE = 0x01000002;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_PERF_COUNTERS 0x01000003")]
+        internal const uint QUIC_PARAM_GLOBAL_PERF_COUNTERS = 0x01000003;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_LIBRARY_VERSION 0x01000004")]
+        internal const uint QUIC_PARAM_GLOBAL_LIBRARY_VERSION = 0x01000004;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_SETTINGS 0x01000005")]
+        internal const uint QUIC_PARAM_GLOBAL_SETTINGS = 0x01000005;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_GLOBAL_SETTINGS 0x01000006")]
+        internal const uint QUIC_PARAM_GLOBAL_GLOBAL_SETTINGS = 0x01000006;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_VERSION_SETTINGS 0x01000007")]
+        internal const uint QUIC_PARAM_GLOBAL_VERSION_SETTINGS = 0x01000007;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH 0x01000008")]
+        internal const uint QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH = 0x01000008;
+
+        [NativeTypeName("#define QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS 0x01000009")]
+        internal const uint QUIC_PARAM_GLOBAL_DATAPATH_PROCESSORS = 0x01000009;
+
+        [NativeTypeName("#define QUIC_PARAM_CONFIGURATION_SETTINGS 0x03000000")]
+        internal const uint QUIC_PARAM_CONFIGURATION_SETTINGS = 0x03000000;
+
+        [NativeTypeName("#define QUIC_PARAM_CONFIGURATION_TICKET_KEYS 0x03000001")]
+        internal const uint QUIC_PARAM_CONFIGURATION_TICKET_KEYS = 0x03000001;
+
+        [NativeTypeName("#define QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS 0x03000002")]
+        internal const uint QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS = 0x03000002;
+
+        [NativeTypeName("#define QUIC_PARAM_LISTENER_LOCAL_ADDRESS 0x04000000")]
+        internal const uint QUIC_PARAM_LISTENER_LOCAL_ADDRESS = 0x04000000;
+
+        [NativeTypeName("#define QUIC_PARAM_LISTENER_STATS 0x04000001")]
+        internal const uint QUIC_PARAM_LISTENER_STATS = 0x04000001;
+
+        [NativeTypeName("#define QUIC_PARAM_LISTENER_CIBIR_ID 0x04000002")]
+        internal const uint QUIC_PARAM_LISTENER_CIBIR_ID = 0x04000002;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_QUIC_VERSION 0x05000000")]
+        internal const uint QUIC_PARAM_CONN_QUIC_VERSION = 0x05000000;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_LOCAL_ADDRESS 0x05000001")]
+        internal const uint QUIC_PARAM_CONN_LOCAL_ADDRESS = 0x05000001;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_REMOTE_ADDRESS 0x05000002")]
+        internal const uint QUIC_PARAM_CONN_REMOTE_ADDRESS = 0x05000002;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_IDEAL_PROCESSOR 0x05000003")]
+        internal const uint QUIC_PARAM_CONN_IDEAL_PROCESSOR = 0x05000003;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_SETTINGS 0x05000004")]
+        internal const uint QUIC_PARAM_CONN_SETTINGS = 0x05000004;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_STATISTICS 0x05000005")]
+        internal const uint QUIC_PARAM_CONN_STATISTICS = 0x05000005;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_STATISTICS_PLAT 0x05000006")]
+        internal const uint QUIC_PARAM_CONN_STATISTICS_PLAT = 0x05000006;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_SHARE_UDP_BINDING 0x05000007")]
+        internal const uint QUIC_PARAM_CONN_SHARE_UDP_BINDING = 0x05000007;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT 0x05000008")]
+        internal const uint QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT = 0x05000008;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT 0x05000009")]
+        internal const uint QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT = 0x05000009;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_MAX_STREAM_IDS 0x0500000A")]
+        internal const uint QUIC_PARAM_CONN_MAX_STREAM_IDS = 0x0500000A;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_CLOSE_REASON_PHRASE 0x0500000B")]
+        internal const uint QUIC_PARAM_CONN_CLOSE_REASON_PHRASE = 0x0500000B;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME 0x0500000C")]
+        internal const uint QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME = 0x0500000C;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_DATAGRAM_RECEIVE_ENABLED 0x0500000D")]
+        internal const uint QUIC_PARAM_CONN_DATAGRAM_RECEIVE_ENABLED = 0x0500000D;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_DATAGRAM_SEND_ENABLED 0x0500000E")]
+        internal const uint QUIC_PARAM_CONN_DATAGRAM_SEND_ENABLED = 0x0500000E;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION 0x0500000F")]
+        internal const uint QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION = 0x0500000F;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_RESUMPTION_TICKET 0x05000010")]
+        internal const uint QUIC_PARAM_CONN_RESUMPTION_TICKET = 0x05000010;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID 0x05000011")]
+        internal const uint QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID = 0x05000011;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_LOCAL_INTERFACE 0x05000012")]
+        internal const uint QUIC_PARAM_CONN_LOCAL_INTERFACE = 0x05000012;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_TLS_SECRETS 0x05000013")]
+        internal const uint QUIC_PARAM_CONN_TLS_SECRETS = 0x05000013;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_VERSION_SETTINGS 0x05000014")]
+        internal const uint QUIC_PARAM_CONN_VERSION_SETTINGS = 0x05000014;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_CIBIR_ID 0x05000015")]
+        internal const uint QUIC_PARAM_CONN_CIBIR_ID = 0x05000015;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_STATISTICS_V2 0x05000016")]
+        internal const uint QUIC_PARAM_CONN_STATISTICS_V2 = 0x05000016;
+
+        [NativeTypeName("#define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017")]
+        internal const uint QUIC_PARAM_CONN_STATISTICS_V2_PLAT = 0x05000017;
+
+        [NativeTypeName("#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x06000000")]
+        internal const uint QUIC_PARAM_TLS_HANDSHAKE_INFO = 0x06000000;
+
+        [NativeTypeName("#define QUIC_PARAM_TLS_NEGOTIATED_ALPN 0x06000001")]
+        internal const uint QUIC_PARAM_TLS_NEGOTIATED_ALPN = 0x06000001;
+
+        [NativeTypeName("#define QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W 0x07000000")]
+        internal const uint QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W = 0x07000000;
+
+        [NativeTypeName("#define QUIC_PARAM_STREAM_ID 0x08000000")]
+        internal const uint QUIC_PARAM_STREAM_ID = 0x08000000;
+
+        [NativeTypeName("#define QUIC_PARAM_STREAM_0RTT_LENGTH 0x08000001")]
+        internal const uint QUIC_PARAM_STREAM_0RTT_LENGTH = 0x08000001;
+
+        [NativeTypeName("#define QUIC_PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE 0x08000002")]
+        internal const uint QUIC_PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE = 0x08000002;
+
+        [NativeTypeName("#define QUIC_PARAM_STREAM_PRIORITY 0x08000003")]
+        internal const uint QUIC_PARAM_STREAM_PRIORITY = 0x08000003;
+
+        [NativeTypeName("#define QUIC_API_VERSION_2 2")]
+        internal const uint QUIC_API_VERSION_2 = 2;
+    }
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_linux.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_linux.cs
new file mode 100644 (file)
index 0000000..67e3967
--- /dev/null
@@ -0,0 +1,109 @@
+#pragma warning disable IDE0073
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+//
+#pragma warning restore IDE0073
+
+namespace Microsoft.Quic
+{
+    internal static unsafe partial class MsQuic_Linux
+    {
+        [NativeTypeName("#define QUIC_STATUS_SUCCESS ((QUIC_STATUS)0)")]
+        public const int QUIC_STATUS_SUCCESS = ((int)(0));
+
+        [NativeTypeName("#define QUIC_STATUS_PENDING ((QUIC_STATUS)-2)")]
+        public const int QUIC_STATUS_PENDING = unchecked((int)(-2));
+
+        [NativeTypeName("#define QUIC_STATUS_CONTINUE ((QUIC_STATUS)-1)")]
+        public const int QUIC_STATUS_CONTINUE = unchecked((int)(-1));
+
+        [NativeTypeName("#define QUIC_STATUS_OUT_OF_MEMORY ((QUIC_STATUS)ENOMEM)")]
+        public const int QUIC_STATUS_OUT_OF_MEMORY = ((int)(12));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_PARAMETER ((QUIC_STATUS)EINVAL)")]
+        public const int QUIC_STATUS_INVALID_PARAMETER = ((int)(22));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_STATE ((QUIC_STATUS)EPERM)")]
+        public const int QUIC_STATUS_INVALID_STATE = ((int)(1));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_SUPPORTED ((QUIC_STATUS)EOPNOTSUPP)")]
+        public const int QUIC_STATUS_NOT_SUPPORTED = ((int)(95));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_FOUND ((QUIC_STATUS)ENOENT)")]
+        public const int QUIC_STATUS_NOT_FOUND = ((int)(2));
+
+        [NativeTypeName("#define QUIC_STATUS_BUFFER_TOO_SMALL ((QUIC_STATUS)EOVERFLOW)")]
+        public const int QUIC_STATUS_BUFFER_TOO_SMALL = ((int)(75));
+
+        [NativeTypeName("#define QUIC_STATUS_HANDSHAKE_FAILURE ((QUIC_STATUS)ECONNABORTED)")]
+        public const int QUIC_STATUS_HANDSHAKE_FAILURE = ((int)(103));
+
+        [NativeTypeName("#define QUIC_STATUS_ABORTED ((QUIC_STATUS)ECANCELED)")]
+        public const int QUIC_STATUS_ABORTED = ((int)(125));
+
+        [NativeTypeName("#define QUIC_STATUS_ADDRESS_IN_USE ((QUIC_STATUS)EADDRINUSE)")]
+        public const int QUIC_STATUS_ADDRESS_IN_USE = ((int)(98));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_TIMEOUT ((QUIC_STATUS)ETIMEDOUT)")]
+        public const int QUIC_STATUS_CONNECTION_TIMEOUT = ((int)(110));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_IDLE ((QUIC_STATUS)ETIME)")]
+        public const int QUIC_STATUS_CONNECTION_IDLE = ((int)(62));
+
+        [NativeTypeName("#define QUIC_STATUS_INTERNAL_ERROR ((QUIC_STATUS)EIO)")]
+        public const int QUIC_STATUS_INTERNAL_ERROR = ((int)(5));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_REFUSED ((QUIC_STATUS)ECONNREFUSED)")]
+        public const int QUIC_STATUS_CONNECTION_REFUSED = ((int)(111));
+
+        [NativeTypeName("#define QUIC_STATUS_PROTOCOL_ERROR ((QUIC_STATUS)EPROTO)")]
+        public const int QUIC_STATUS_PROTOCOL_ERROR = ((int)(71));
+
+        [NativeTypeName("#define QUIC_STATUS_VER_NEG_ERROR ((QUIC_STATUS)EPROTONOSUPPORT)")]
+        public const int QUIC_STATUS_VER_NEG_ERROR = ((int)(93));
+
+        [NativeTypeName("#define QUIC_STATUS_UNREACHABLE ((QUIC_STATUS)EHOSTUNREACH)")]
+        public const int QUIC_STATUS_UNREACHABLE = ((int)(113));
+
+        [NativeTypeName("#define QUIC_STATUS_TLS_ERROR ((QUIC_STATUS)ENOKEY)")]
+        public const int QUIC_STATUS_TLS_ERROR = ((int)(126));
+
+        [NativeTypeName("#define QUIC_STATUS_USER_CANCELED ((QUIC_STATUS)EOWNERDEAD)")]
+        public const int QUIC_STATUS_USER_CANCELED = ((int)(130));
+
+        [NativeTypeName("#define QUIC_STATUS_ALPN_NEG_FAILURE ((QUIC_STATUS)ENOPROTOOPT)")]
+        public const int QUIC_STATUS_ALPN_NEG_FAILURE = ((int)(92));
+
+        [NativeTypeName("#define QUIC_STATUS_STREAM_LIMIT_REACHED ((QUIC_STATUS)ESTRPIPE)")]
+        public const int QUIC_STATUS_STREAM_LIMIT_REACHED = ((int)(86));
+
+        [NativeTypeName("#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0)")]
+        public const int QUIC_STATUS_CLOSE_NOTIFY = ((int)(0xff & 0) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42)")]
+        public const int QUIC_STATUS_BAD_CERTIFICATE = ((int)(0xff & 42) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_UNSUPPORTED_CERTIFICATE QUIC_STATUS_TLS_ALERT(43)")]
+        public const int QUIC_STATUS_UNSUPPORTED_CERTIFICATE = ((int)(0xff & 43) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_REVOKED_CERTIFICATE QUIC_STATUS_TLS_ALERT(44)")]
+        public const int QUIC_STATUS_REVOKED_CERTIFICATE = ((int)(0xff & 44) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45)")]
+        public const int QUIC_STATUS_EXPIRED_CERTIFICATE = ((int)(0xff & 45) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_UNKNOWN_CERTIFICATE QUIC_STATUS_TLS_ALERT(46)")]
+        public const int QUIC_STATUS_UNKNOWN_CERTIFICATE = ((int)(0xff & 46) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_EXPIRED QUIC_STATUS_CERT_ERROR(1)")]
+        public const int QUIC_STATUS_CERT_EXPIRED = ((int)(1) + 512 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_UNTRUSTED_ROOT QUIC_STATUS_CERT_ERROR(2)")]
+        public const int QUIC_STATUS_CERT_UNTRUSTED_ROOT = ((int)(2) + 512 + 200000000);
+
+        public const int QUIC_ADDRESS_FAMILY_UNSPEC = 0;
+        public const int QUIC_ADDRESS_FAMILY_INET = 2;
+        public const int QUIC_ADDRESS_FAMILY_INET6 = 10;
+    }
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_macos.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_macos.cs
new file mode 100644 (file)
index 0000000..00a3ad7
--- /dev/null
@@ -0,0 +1,109 @@
+#pragma warning disable IDE0073
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+//
+#pragma warning restore IDE0073
+
+namespace Microsoft.Quic
+{
+    internal static unsafe partial class MsQuic_MacOS
+    {
+        [NativeTypeName("#define QUIC_STATUS_SUCCESS ((QUIC_STATUS)0)")]
+        public const int QUIC_STATUS_SUCCESS = ((int)(0));
+
+        [NativeTypeName("#define QUIC_STATUS_PENDING ((QUIC_STATUS)-2)")]
+        public const int QUIC_STATUS_PENDING = unchecked((int)(-2));
+
+        [NativeTypeName("#define QUIC_STATUS_CONTINUE ((QUIC_STATUS)-1)")]
+        public const int QUIC_STATUS_CONTINUE = unchecked((int)(-1));
+
+        [NativeTypeName("#define QUIC_STATUS_OUT_OF_MEMORY ((QUIC_STATUS)ENOMEM)")]
+        public const int QUIC_STATUS_OUT_OF_MEMORY = ((int)(12));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_PARAMETER ((QUIC_STATUS)EINVAL)")]
+        public const int QUIC_STATUS_INVALID_PARAMETER = ((int)(22));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_STATE ((QUIC_STATUS)EPERM)")]
+        public const int QUIC_STATUS_INVALID_STATE = ((int)(1));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_SUPPORTED ((QUIC_STATUS)EOPNOTSUPP)")]
+        public const int QUIC_STATUS_NOT_SUPPORTED = ((int)(102));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_FOUND ((QUIC_STATUS)ENOENT)")]
+        public const int QUIC_STATUS_NOT_FOUND = ((int)(2));
+
+        [NativeTypeName("#define QUIC_STATUS_BUFFER_TOO_SMALL ((QUIC_STATUS)EOVERFLOW)")]
+        public const int QUIC_STATUS_BUFFER_TOO_SMALL = ((int)(84));
+
+        [NativeTypeName("#define QUIC_STATUS_HANDSHAKE_FAILURE ((QUIC_STATUS)ECONNABORTED)")]
+        public const int QUIC_STATUS_HANDSHAKE_FAILURE = ((int)(53));
+
+        [NativeTypeName("#define QUIC_STATUS_ABORTED ((QUIC_STATUS)ECANCELED)")]
+        public const int QUIC_STATUS_ABORTED = ((int)(89));
+
+        [NativeTypeName("#define QUIC_STATUS_ADDRESS_IN_USE ((QUIC_STATUS)EADDRINUSE)")]
+        public const int QUIC_STATUS_ADDRESS_IN_USE = ((int)(48));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_TIMEOUT ((QUIC_STATUS)ETIMEDOUT)")]
+        public const int QUIC_STATUS_CONNECTION_TIMEOUT = ((int)(60));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_IDLE ((QUIC_STATUS)ETIME)")]
+        public const int QUIC_STATUS_CONNECTION_IDLE = ((int)(101));
+
+        [NativeTypeName("#define QUIC_STATUS_INTERNAL_ERROR ((QUIC_STATUS)EIO)")]
+        public const int QUIC_STATUS_INTERNAL_ERROR = ((int)(5));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_REFUSED ((QUIC_STATUS)ECONNREFUSED)")]
+        public const int QUIC_STATUS_CONNECTION_REFUSED = ((int)(61));
+
+        [NativeTypeName("#define QUIC_STATUS_PROTOCOL_ERROR ((QUIC_STATUS)EPROTO)")]
+        public const int QUIC_STATUS_PROTOCOL_ERROR = ((int)(100));
+
+        [NativeTypeName("#define QUIC_STATUS_VER_NEG_ERROR ((QUIC_STATUS)EPROTONOSUPPORT)")]
+        public const int QUIC_STATUS_VER_NEG_ERROR = ((int)(43));
+
+        [NativeTypeName("#define QUIC_STATUS_UNREACHABLE ((QUIC_STATUS)EHOSTUNREACH)")]
+        public const int QUIC_STATUS_UNREACHABLE = ((int)(65));
+
+        [NativeTypeName("#define QUIC_STATUS_TLS_ERROR ((QUIC_STATUS)ENOKEY)")]
+        public const int QUIC_STATUS_TLS_ERROR = ((int)(126));
+
+        [NativeTypeName("#define QUIC_STATUS_USER_CANCELED ((QUIC_STATUS)EOWNERDEAD)")]
+        public const int QUIC_STATUS_USER_CANCELED = ((int)(105));
+
+        [NativeTypeName("#define QUIC_STATUS_ALPN_NEG_FAILURE ((QUIC_STATUS)ENOPROTOOPT)")]
+        public const int QUIC_STATUS_ALPN_NEG_FAILURE = ((int)(42));
+
+        [NativeTypeName("#define QUIC_STATUS_STREAM_LIMIT_REACHED ((QUIC_STATUS)ESTRPIPE)")]
+        public const int QUIC_STATUS_STREAM_LIMIT_REACHED = ((int)(86));
+
+        [NativeTypeName("#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0)")]
+        public const int QUIC_STATUS_CLOSE_NOTIFY = ((int)(0xff & 0) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42)")]
+        public const int QUIC_STATUS_BAD_CERTIFICATE = ((int)(0xff & 42) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_UNSUPPORTED_CERTIFICATE QUIC_STATUS_TLS_ALERT(43)")]
+        public const int QUIC_STATUS_UNSUPPORTED_CERTIFICATE = ((int)(0xff & 43) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_REVOKED_CERTIFICATE QUIC_STATUS_TLS_ALERT(44)")]
+        public const int QUIC_STATUS_REVOKED_CERTIFICATE = ((int)(0xff & 44) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45)")]
+        public const int QUIC_STATUS_EXPIRED_CERTIFICATE = ((int)(0xff & 45) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_UNKNOWN_CERTIFICATE QUIC_STATUS_TLS_ALERT(46)")]
+        public const int QUIC_STATUS_UNKNOWN_CERTIFICATE = ((int)(0xff & 46) + 256 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_EXPIRED QUIC_STATUS_CERT_ERROR(1)")]
+        public const int QUIC_STATUS_CERT_EXPIRED = ((int)(1) + 512 + 200000000);
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_UNTRUSTED_ROOT QUIC_STATUS_CERT_ERROR(2)")]
+        public const int QUIC_STATUS_CERT_UNTRUSTED_ROOT = ((int)(2) + 512 + 200000000);
+
+        public const int QUIC_ADDRESS_FAMILY_UNSPEC = 0;
+        public const int QUIC_ADDRESS_FAMILY_INET = 2;
+        public const int QUIC_ADDRESS_FAMILY_INET6 = 30;
+    }
+}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_windows.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/msquic_generated_windows.cs
new file mode 100644 (file)
index 0000000..ee8cf6b
--- /dev/null
@@ -0,0 +1,109 @@
+#pragma warning disable IDE0073
+//
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+//
+#pragma warning restore IDE0073
+
+namespace Microsoft.Quic
+{
+    internal static partial class MsQuic_Windows
+    {
+        [NativeTypeName("#define QUIC_STATUS_SUCCESS S_OK")]
+        public const int QUIC_STATUS_SUCCESS = ((int)(0));
+
+        [NativeTypeName("#define QUIC_STATUS_PENDING SUCCESS_HRESULT_FROM_WIN32(ERROR_IO_PENDING)")]
+        public const int QUIC_STATUS_PENDING = ((int)(((997) & 0x0000FFFF) | (7 << 16)));
+
+        [NativeTypeName("#define QUIC_STATUS_CONTINUE SUCCESS_HRESULT_FROM_WIN32(ERROR_CONTINUE)")]
+        public const int QUIC_STATUS_CONTINUE = ((int)(((1246) & 0x0000FFFF) | (7 << 16)));
+
+        [NativeTypeName("#define QUIC_STATUS_OUT_OF_MEMORY E_OUTOFMEMORY")]
+        public const int QUIC_STATUS_OUT_OF_MEMORY = unchecked((int)(0x8007000E));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_PARAMETER E_INVALIDARG")]
+        public const int QUIC_STATUS_INVALID_PARAMETER = unchecked((int)(0x80070057));
+
+        [NativeTypeName("#define QUIC_STATUS_INVALID_STATE QUIC_STATUS_HRESULT_FROM_WIN32(ERROR_INVALID_STATE)")]
+        public const int QUIC_STATUS_INVALID_STATE = unchecked((int)(5023) <= 0 ? ((int)(5023)) : ((int)(((5023) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_SUPPORTED E_NOINTERFACE")]
+        public const int QUIC_STATUS_NOT_SUPPORTED = unchecked((int)(0x80004002));
+
+        [NativeTypeName("#define QUIC_STATUS_NOT_FOUND QUIC_STATUS_HRESULT_FROM_WIN32(ERROR_NOT_FOUND)")]
+        public const int QUIC_STATUS_NOT_FOUND = unchecked((int)(1168) <= 0 ? ((int)(1168)) : ((int)(((1168) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_BUFFER_TOO_SMALL QUIC_STATUS_HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)")]
+        public const int QUIC_STATUS_BUFFER_TOO_SMALL = unchecked((int)(122) <= 0 ? ((int)(122)) : ((int)(((122) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_HANDSHAKE_FAILURE ERROR_QUIC_HANDSHAKE_FAILURE")]
+        public const int QUIC_STATUS_HANDSHAKE_FAILURE = unchecked((int)(0x80410000));
+
+        [NativeTypeName("#define QUIC_STATUS_ABORTED E_ABORT")]
+        public const int QUIC_STATUS_ABORTED = unchecked((int)(0x80004004));
+
+        [NativeTypeName("#define QUIC_STATUS_ADDRESS_IN_USE QUIC_STATUS_HRESULT_FROM_WIN32(WSAEADDRINUSE)")]
+        public const int QUIC_STATUS_ADDRESS_IN_USE = unchecked((int)(10048) <= 0 ? ((int)(10048)) : ((int)(((10048) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_TIMEOUT ERROR_QUIC_CONNECTION_TIMEOUT")]
+        public const int QUIC_STATUS_CONNECTION_TIMEOUT = unchecked((int)(0x80410006));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_IDLE ERROR_QUIC_CONNECTION_IDLE")]
+        public const int QUIC_STATUS_CONNECTION_IDLE = unchecked((int)(0x80410005));
+
+        [NativeTypeName("#define QUIC_STATUS_UNREACHABLE QUIC_STATUS_HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE)")]
+        public const int QUIC_STATUS_UNREACHABLE = unchecked((int)(1232) <= 0 ? ((int)(1232)) : ((int)(((1232) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_INTERNAL_ERROR ERROR_QUIC_INTERNAL_ERROR")]
+        public const int QUIC_STATUS_INTERNAL_ERROR = unchecked((int)(0x80410003));
+
+        [NativeTypeName("#define QUIC_STATUS_CONNECTION_REFUSED QUIC_STATUS_HRESULT_FROM_WIN32(ERROR_CONNECTION_REFUSED)")]
+        public const int QUIC_STATUS_CONNECTION_REFUSED = unchecked((int)(1225) <= 0 ? ((int)(1225)) : ((int)(((1225) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_PROTOCOL_ERROR ERROR_QUIC_PROTOCOL_VIOLATION")]
+        public const int QUIC_STATUS_PROTOCOL_ERROR = unchecked((int)(0x80410004));
+
+        [NativeTypeName("#define QUIC_STATUS_VER_NEG_ERROR ERROR_QUIC_VER_NEG_FAILURE")]
+        public const int QUIC_STATUS_VER_NEG_ERROR = unchecked((int)(0x80410001));
+
+        [NativeTypeName("#define QUIC_STATUS_TLS_ERROR QUIC_STATUS_HRESULT_FROM_WIN32(WSA_SECURE_HOST_NOT_FOUND)")]
+        public const int QUIC_STATUS_TLS_ERROR = unchecked((int)(11032) <= 0 ? ((int)(11032)) : ((int)(((11032) & 0x0000FFFF) | (7 << 16) | 0x80000000)));
+
+        [NativeTypeName("#define QUIC_STATUS_USER_CANCELED ERROR_QUIC_USER_CANCELED")]
+        public const int QUIC_STATUS_USER_CANCELED = unchecked((int)(0x80410002));
+
+        [NativeTypeName("#define QUIC_STATUS_ALPN_NEG_FAILURE ERROR_QUIC_ALPN_NEG_FAILURE")]
+        public const int QUIC_STATUS_ALPN_NEG_FAILURE = unchecked((int)(0x80410007));
+
+        [NativeTypeName("#define QUIC_STATUS_STREAM_LIMIT_REACHED ERROR_QUIC_STREAM_LIMIT_REACHED")]
+        public const int QUIC_STATUS_STREAM_LIMIT_REACHED = unchecked((int)(0x80410008));
+
+        [NativeTypeName("#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0)")]
+        public const int QUIC_STATUS_CLOSE_NOTIFY = unchecked(((int)(0x80410100)) | (0xff & 0));
+
+        [NativeTypeName("#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42)")]
+        public const int QUIC_STATUS_BAD_CERTIFICATE = unchecked(((int)(0x80410100)) | (0xff & 42));
+
+        [NativeTypeName("#define QUIC_STATUS_UNSUPPORTED_CERTIFICATE QUIC_STATUS_TLS_ALERT(43)")]
+        public const int QUIC_STATUS_UNSUPPORTED_CERTIFICATE = unchecked(((int)(0x80410100)) | (0xff & 43));
+
+        [NativeTypeName("#define QUIC_STATUS_REVOKED_CERTIFICATE QUIC_STATUS_TLS_ALERT(44)")]
+        public const int QUIC_STATUS_REVOKED_CERTIFICATE = unchecked(((int)(0x80410100)) | (0xff & 44));
+
+        [NativeTypeName("#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45)")]
+        public const int QUIC_STATUS_EXPIRED_CERTIFICATE = unchecked(((int)(0x80410100)) | (0xff & 45));
+
+        [NativeTypeName("#define QUIC_STATUS_UNKNOWN_CERTIFICATE QUIC_STATUS_TLS_ALERT(46)")]
+        public const int QUIC_STATUS_UNKNOWN_CERTIFICATE = unchecked(((int)(0x80410100)) | (0xff & 46));
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_EXPIRED CERT_E_EXPIRED")]
+        public const int QUIC_STATUS_CERT_EXPIRED = unchecked((int)(0x800B0101));
+
+        [NativeTypeName("#define QUIC_STATUS_CERT_UNTRUSTED_ROOT CERT_E_UNTRUSTEDROOT")]
+        public const int QUIC_STATUS_CERT_UNTRUSTED_ROOT = unchecked((int)(0x800B0109));
+
+        public const int QUIC_ADDRESS_FAMILY_UNSPEC = 0;
+        public const int QUIC_ADDRESS_FAMILY_INET = 2;
+        public const int QUIC_ADDRESS_FAMILY_INET6 = 23;
+    }
+}
index f5d3aba..c2483d6 100644 (file)
@@ -5,6 +5,7 @@ using System.Diagnostics;
 using System.Net.Quic.Implementations.MsQuic.Internal;
 using System.Net.Security;
 using System.Net.Sockets;
+using System.Runtime.CompilerServices;
 using System.Runtime.ExceptionServices;
 using System.Runtime.InteropServices;
 using System.Security.Authentication;
@@ -13,7 +14,8 @@ using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading.Channels;
 using System.Threading.Tasks;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
+using Microsoft.Quic;
+using static Microsoft.Quic.MsQuic;
 
 namespace System.Net.Quic.Implementations.MsQuic
 {
@@ -23,9 +25,6 @@ namespace System.Net.Quic.Implementations.MsQuic
         private static readonly Oid s_serverAuthOid = new Oid("1.3.6.1.5.5.7.3.1", "1.3.6.1.5.5.7.3.1");
         private const uint DefaultResetValue = 0xffffffff; // Arbitrary value unlikely to conflict with application protocols.
 
-        // Delegate that wraps the static function that will be called when receiving an event.
-        private static unsafe readonly ConnectionCallbackDelegate s_connectionDelegate = new ConnectionCallbackDelegate(NativeCallbackHandler);
-
         // TODO: remove this.
         // This is only used for client-initiated connections, and isn't needed even then once Connect() has been called.
         private SafeMsQuicConfigurationHandle? _configuration;
@@ -40,7 +39,6 @@ namespace System.Net.Quic.Implementations.MsQuic
         internal sealed class State
         {
             public SafeMsQuicConnectionHandle Handle = null!; // set inside of MsQuicConnection ctor.
-            public string TraceId = null!; // set inside of MsQuicConnection ctor.
 
             public GCHandle StateGCHandle;
 
@@ -48,9 +46,9 @@ namespace System.Net.Quic.Implementations.MsQuic
             public MsQuicConnection? Connection;
             public MsQuicListener.State? ListenerState;
 
-            public TaskCompletionSource<uint>? ConnectTcs;
+            public TaskCompletionSource<int>? ConnectTcs;
             // TODO: only allocate these when there is an outstanding shutdown.
-            public readonly TaskCompletionSource<uint> ShutdownTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously);
+            public readonly TaskCompletionSource<int> ShutdownTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
 
             public bool Connected;
             public long AbortErrorCode = -1;
@@ -84,7 +82,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
                 if (releaseHandles)
                 {
-                    if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"{TraceId} releasing handle after last stream.");
+                    if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"{Handle} releasing handle after last stream.");
                     Handle?.Dispose();
                 }
             }
@@ -127,10 +125,8 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        internal string TraceId() => _state.TraceId;
-
         // constructor for inbound connections
-        public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, MsQuicListener.State listenerState, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback? remoteCertificateValidationCallback = null, ServerCertificateSelectionCallback? serverCertificateSelectionCallback = null)
+        public unsafe MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, MsQuicListener.State listenerState, SafeMsQuicConnectionHandle handle, bool remoteCertificateRequired = false, X509RevocationMode revocationMode = X509RevocationMode.Offline, RemoteCertificateValidationCallback? remoteCertificateValidationCallback = null, ServerCertificateSelectionCallback? serverCertificateSelectionCallback = null)
         {
             _state.Handle = handle;
             _state.StateGCHandle = GCHandle.Alloc(_state);
@@ -144,10 +140,11 @@ namespace System.Net.Quic.Implementations.MsQuic
             try
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicApi.Api.SetCallbackHandlerDelegate(
-                    _state.Handle,
-                    s_connectionDelegate,
-                    GCHandle.ToIntPtr(_state.StateGCHandle));
+                delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, QUIC_CONNECTION_EVENT*, int> nativeCallback = &NativeCallback;
+                MsQuicApi.Api.ApiTable->SetCallbackHandler(
+                    _state.Handle.QuicHandle,
+                    nativeCallback,
+                    (void*)GCHandle.ToIntPtr(_state.StateGCHandle));
             }
             catch
             {
@@ -156,15 +153,14 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
             _state.ListenerState = listenerState;
-            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(_state, $"{TraceId()} Inbound connection created");
+                NetEventSource.Info(_state, $"{handle} Inbound connection created");
             }
         }
 
         // constructor for outbound connections
-        public MsQuicConnection(QuicClientConnectionOptions options)
+        public unsafe MsQuicConnection(QuicClientConnectionOptions options)
         {
             ArgumentNullException.ThrowIfNull(options.RemoteEndPoint, nameof(options.RemoteEndPoint));
 
@@ -181,14 +177,14 @@ namespace System.Net.Quic.Implementations.MsQuic
             _state.StateGCHandle = GCHandle.Alloc(_state);
             try
             {
+                QUIC_HANDLE* handle;
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                uint status = MsQuicApi.Api.ConnectionOpenDelegate(
-                    MsQuicApi.Api.Registration,
-                    s_connectionDelegate,
-                    GCHandle.ToIntPtr(_state.StateGCHandle),
-                    out _state.Handle);
-
-                QuicExceptionHelpers.ThrowIfFailed(status, "Could not open the connection.");
+                ThrowIfFailure(MsQuicApi.Api.ApiTable->ConnectionOpen(
+                    MsQuicApi.Api.Registration.QuicHandle,
+                    &NativeCallback,
+                    (void*)GCHandle.ToIntPtr(_state.StateGCHandle),
+                    &handle), "Could not open the connection");
+                _state.Handle = new SafeMsQuicConnectionHandle(handle);
             }
             catch
             {
@@ -196,10 +192,9 @@ namespace System.Net.Quic.Implementations.MsQuic
                 throw;
             }
 
-            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(_state, $"{TraceId()} Outbound connection created");
+                NetEventSource.Info(_state, $"{_state.Handle} Outbound connection created");
             }
         }
 
@@ -213,11 +208,11 @@ namespace System.Net.Quic.Implementations.MsQuic
 
         internal override bool Connected => _state.Connected;
 
-        private static uint HandleEventConnected(State state, ref ConnectionEvent connectionEvent)
+        private static unsafe int HandleEventConnected(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
             if (state.Connected)
             {
-                return MsQuicStatusCodes.Success;
+                return QUIC_STATUS_SUCCESS;
             }
 
             if (state.IsServer)
@@ -233,14 +228,14 @@ namespace System.Net.Quic.Implementations.MsQuic
                         // Move connection from pending to Accept queue and hand it out.
                         if (listenerState.AcceptConnectionQueue.Writer.TryWrite(connection))
                         {
-                            return MsQuicStatusCodes.Success;
+                            return QUIC_STATUS_SUCCESS;
                         }
                         // Listener is closed
                         connection.Dispose();
                     }
                 }
 
-                return MsQuicStatusCodes.UserCanceled;
+                return QUIC_STATUS_USER_CANCELED;
             }
             else
             {
@@ -249,27 +244,26 @@ namespace System.Net.Quic.Implementations.MsQuic
 
 
                 Debug.Assert(state.Connection != null);
-                state.Connection._localEndPoint = MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, state.Handle, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);
-                state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
+                state.Connection._localEndPoint = MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_CONN_LOCAL_ADDRESS);
+                state.Connection.SetNegotiatedAlpn((IntPtr)connectionEvent.CONNECTED.NegotiatedAlpn, connectionEvent.CONNECTED.NegotiatedAlpnLength);
                 state.Connection = null;
 
                 state.Connected = true;
-                state.ConnectTcs!.SetResult(MsQuicStatusCodes.Success);
+                state.ConnectTcs!.SetResult(QUIC_STATUS_SUCCESS);
                 state.ConnectTcs = null;
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventShutdownInitiatedByTransport(State state, ref ConnectionEvent connectionEvent)
+        private static int HandleEventShutdownInitiatedByTransport(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
             if (!state.Connected && state.ConnectTcs != null)
             {
                 Debug.Assert(state.Connection != null);
                 state.Connection = null;
 
-                uint hresult = connectionEvent.Data.ShutdownInitiatedByTransport.Status;
-                Exception ex = QuicExceptionHelpers.CreateExceptionForHResult(hresult, "Connection has been shutdown by transport.");
+                Exception ex = new MsQuicException(connectionEvent.SHUTDOWN_INITIATED_BY_TRANSPORT.Status, "Connection has been shutdown by transport");
                 state.ConnectTcs!.SetException(ExceptionDispatchInfo.SetCurrentStackTrace(ex));
                 state.ConnectTcs = null;
             }
@@ -280,24 +274,24 @@ namespace System.Net.Quic.Implementations.MsQuic
             // See: https://github.com/dotnet/runtime/issues/60133
             state.AbortErrorCode = 0;
             state.AcceptQueue.Writer.TryComplete();
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventShutdownInitiatedByPeer(State state, ref ConnectionEvent connectionEvent)
+        private static int HandleEventShutdownInitiatedByPeer(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
-            state.AbortErrorCode = (long)connectionEvent.Data.ShutdownInitiatedByPeer.ErrorCode;
+            state.AbortErrorCode = (long)connectionEvent.SHUTDOWN_INITIATED_BY_PEER.ErrorCode;
             state.AcceptQueue.Writer.TryComplete();
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventShutdownComplete(State state, ref ConnectionEvent connectionEvent)
+        private static int HandleEventShutdownComplete(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
             // This is the final event on the connection, so free the GCHandle used by the event callback.
             state.StateGCHandle.Free();
 
             if (state.ListenerState != null)
             {
-                // This is inbound connection that never got connected - becasue of TLS validation or some other reason.
+                // This is inbound connection that never got connected - because of TLS validation or some other reason.
                 // Remove connection from pending queue and dispose it.
                 if (state.ListenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out MsQuicConnection? connection))
                 {
@@ -309,33 +303,33 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             state.Connection = null;
 
-            state.ShutdownTcs.SetResult(MsQuicStatusCodes.Success);
+            state.ShutdownTcs.SetResult(QUIC_STATUS_SUCCESS);
 
             // Stop accepting new streams.
             state.AcceptQueue.Writer.TryComplete();
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventNewStream(State state, ref ConnectionEvent connectionEvent)
+        private static unsafe int HandleEventNewStream(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
-            var streamHandle = new SafeMsQuicStreamHandle(connectionEvent.Data.PeerStreamStarted.Stream);
-            if (!state.TryQueueNewStream(streamHandle, connectionEvent.Data.PeerStreamStarted.Flags))
+            var streamHandle = new SafeMsQuicStreamHandle(connectionEvent.PEER_STREAM_STARTED.Stream);
+            if (!state.TryQueueNewStream(streamHandle, connectionEvent.PEER_STREAM_STARTED.Flags))
             {
                 // This will call StreamCloseDelegate and free the stream.
                 // We will return Success to the MsQuic to prevent double free.
                 streamHandle.Dispose();
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventStreamsAvailable(State state, ref ConnectionEvent connectionEvent)
+        private static int HandleEventStreamsAvailable(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventPeerCertificateReceived(State state, ref ConnectionEvent connectionEvent)
+        private static unsafe int HandleEventPeerCertificateReceived(State state, ref QUIC_CONNECTION_EVENT connectionEvent)
         {
             SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;
             X509Chain? chain = null;
@@ -346,24 +340,26 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             try
             {
-                if (connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle != IntPtr.Zero)
+                IntPtr certificateHandle = (IntPtr)connectionEvent.PEER_CERTIFICATE_RECEIVED.Certificate;
+                if (certificateHandle != IntPtr.Zero)
                 {
                     if (OperatingSystem.IsWindows())
                     {
-                        certificate = new X509Certificate2(connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle);
+                        certificate = new X509Certificate2(certificateHandle);
                     }
                     else
                     {
                         unsafe
                         {
-                            ReadOnlySpan<QuicBuffer> quicBuffer = new ReadOnlySpan<QuicBuffer>((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateHandle, sizeof(QuicBuffer));
+                            ReadOnlySpan<QUIC_BUFFER> quicBuffer = new ReadOnlySpan<QUIC_BUFFER>((void*)certificateHandle, sizeof(QUIC_BUFFER));
                             certificate = new X509Certificate2(new ReadOnlySpan<byte>(quicBuffer[0].Buffer, (int)quicBuffer[0].Length));
                             certificateBuffer = (IntPtr)quicBuffer[0].Buffer;
                             certificateLength = (int)quicBuffer[0].Length;
 
-                            if (connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle != IntPtr.Zero)
+                            IntPtr chainHandle = (IntPtr)connectionEvent.PEER_CERTIFICATE_RECEIVED.Chain;
+                            if (chainHandle != IntPtr.Zero)
                             {
-                                quicBuffer = new ReadOnlySpan<QuicBuffer>((void*)connectionEvent.Data.PeerCertificateReceived.PlatformCertificateChainHandle, sizeof(QuicBuffer));
+                                quicBuffer = new ReadOnlySpan<QUIC_BUFFER>((void*)chainHandle, sizeof(QUIC_BUFFER));
                                 if (quicBuffer[0].Length != 0 && quicBuffer[0].Buffer != null)
                                 {
                                     additionalCertificates = new X509Certificate2Collection();
@@ -376,7 +372,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
                 if (certificate == null)
                 {
-                    if (NetEventSource.Log.IsEnabled() && state.RemoteCertificateRequired) NetEventSource.Error(state, $"{state.TraceId} Remote certificate required, but no remote certificate received");
+                    if (NetEventSource.Log.IsEnabled() && state.RemoteCertificateRequired) NetEventSource.Error(state, $"{state.Handle} Remote certificate required, but no remote certificate received");
                     sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                 }
                 else
@@ -409,40 +405,40 @@ namespace System.Net.Quic.Implementations.MsQuic
                     state.RemoteCertificateValidationCallback = (_, _, _, _) => success;
 
                     if (!success && NetEventSource.Log.IsEnabled())
-                        NetEventSource.Error(state, $"{state.TraceId} Remote certificate rejected by verification callback");
+                        NetEventSource.Error(state, $"{state.Handle} Remote certificate rejected by verification callback");
 
                     if (!success)
                     {
                         if (state.IsServer)
                         {
-                            return MsQuicStatusCodes.UserCanceled;
+                            return QUIC_STATUS_USER_CANCELED;
                         }
 
                         throw new AuthenticationException(SR.net_quic_cert_custom_validation);
                     }
 
-                    return MsQuicStatusCodes.Success;
+                    return QUIC_STATUS_SUCCESS;
                 }
 
                 if (NetEventSource.Log.IsEnabled())
-                    NetEventSource.Info(state, $"{state.TraceId} Certificate validation for '${certificate?.Subject}' finished with ${sslPolicyErrors}");
+                    NetEventSource.Info(state, $"{state.Handle} Certificate validation for '${certificate?.Subject}' finished with ${sslPolicyErrors}");
 
 
                 if (sslPolicyErrors != SslPolicyErrors.None)
                 {
                     if (state.IsServer)
                     {
-                        return MsQuicStatusCodes.HandshakeFailure;
+                        return QUIC_STATUS_HANDSHAKE_FAILURE;
                     }
 
                     throw new AuthenticationException(SR.Format(SR.net_quic_cert_chain_validation, sslPolicyErrors));
                 }
 
-                return MsQuicStatusCodes.Success;
+                return QUIC_STATUS_SUCCESS;
             }
             catch (Exception ex)
             {
-                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(state, $"{state.TraceId} Certificate validation failed ${ex.Message}");
+                if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(state, $"{state.Handle} Certificate validation failed ${ex.Message}");
                 throw;
             }
         }
@@ -488,22 +484,24 @@ namespace System.Net.Quic.Implementations.MsQuic
             return stream;
         }
 
-        internal override ValueTask<QuicStreamProvider> OpenUnidirectionalStreamAsync(CancellationToken cancellationToken = default) => OpenStreamAsync(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL, cancellationToken);
-        internal override ValueTask<QuicStreamProvider> OpenBidirectionalStreamAsync(CancellationToken cancellationToken = default) => OpenStreamAsync(QUIC_STREAM_OPEN_FLAGS.NONE, cancellationToken);
+        internal override ValueTask<QuicStreamProvider> OpenUnidirectionalStreamAsync(CancellationToken cancellationToken = default)
+            => OpenStreamAsync(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL, cancellationToken);
+        internal override ValueTask<QuicStreamProvider> OpenBidirectionalStreamAsync(CancellationToken cancellationToken = default)
+            => OpenStreamAsync(QUIC_STREAM_OPEN_FLAGS.NONE, cancellationToken);
 
         internal override int GetRemoteAvailableUnidirectionalStreamCount()
         {
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_CONN.LOCAL_UNIDI_STREAM_COUNT);
+            return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT);
         }
 
         internal override int GetRemoteAvailableBidirectionalStreamCount()
         {
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_CONN.LOCAL_BIDI_STREAM_COUNT);
+            return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT);
         }
 
-        internal override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
+        internal unsafe override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
         {
             ThrowIfDisposed();
 
@@ -512,25 +510,24 @@ namespace System.Net.Quic.Implementations.MsQuic
                 throw new InvalidOperationException($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
             }
 
-            QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
+            ushort af = _remoteEndPoint.AddressFamily switch
             {
-                AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
-                AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
-                AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
+                AddressFamily.Unspecified => (ushort)QUIC_ADDRESS_FAMILY_UNSPEC,
+                AddressFamily.InterNetwork => (ushort)QUIC_ADDRESS_FAMILY_INET,
+                AddressFamily.InterNetworkV6 => (ushort)QUIC_ADDRESS_FAMILY_INET6,
                 _ => throw new ArgumentException(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
             };
 
             Debug.Assert(_state.StateGCHandle.IsAllocated);
 
             _state.Connection = this;
-            uint status;
             string targetHost;
             int port;
 
             if (_remoteEndPoint is IPEndPoint ipEndPoint)
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, ipEndPoint);
+                MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_CONN_REMOTE_ADDRESS, ipEndPoint);
                 targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
                 port = ((IPEndPoint)_remoteEndPoint).Port;
 
@@ -547,7 +544,7 @@ namespace System.Net.Quic.Implementations.MsQuic
                 {
                     // This is form of IPAddress and _state.TargetHost is set to different string
                     Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                    MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, new IPEndPoint(address, port));
+                    MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_CONN_REMOTE_ADDRESS, new IPEndPoint(address, port));
                     targetHost = _state.TargetHost!;
                 }
                 else
@@ -561,19 +558,18 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
             // We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
-            var tcs = _state.ConnectTcs = new TaskCompletionSource<uint>(TaskCreationOptions.RunContinuationsAsynchronously);
+            var tcs = _state.ConnectTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
 
+            IntPtr pTargetHost = Marshal.StringToCoTaskMemAnsi(targetHost);
             try
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                status = MsQuicApi.Api.ConnectionStartDelegate(
-                    _state.Handle,
-                    _configuration,
+                ThrowIfFailure(MsQuicApi.Api.ApiTable->ConnectionStart(
+                    _state.Handle.QuicHandle,
+                    _configuration.QuicHandle,
                     af,
-                    targetHost,
-                    (ushort)port);
-
-                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
+                    (sbyte*)pTargetHost,
+                    (ushort)port), "Failed to connect to peer");
 
                 // this handle is ref counted by MsQuic, so safe to dispose here.
                 _configuration.Dispose();
@@ -584,11 +580,15 @@ namespace System.Net.Quic.Implementations.MsQuic
                 _state.Connection = null;
                 throw;
             }
+            finally
+            {
+                Marshal.FreeCoTaskMem(pTargetHost);
+            }
 
             return new ValueTask(tcs.Task);
         }
 
-        private ValueTask ShutdownAsync(
+        private unsafe ValueTask ShutdownAsync(
             QUIC_CONNECTION_SHUTDOWN_FLAGS Flags,
             long ErrorCode)
         {
@@ -599,10 +599,10 @@ namespace System.Net.Quic.Implementations.MsQuic
             try
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicApi.Api.ConnectionShutdownDelegate(
-                    _state.Handle,
+                MsQuicApi.Api.ApiTable->ConnectionShutdown(
+                    _state.Handle.QuicHandle,
                     Flags,
-                    ErrorCode);
+                    (ulong)ErrorCode);
             }
             catch
             {
@@ -623,19 +623,19 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        private static unsafe uint NativeCallbackHandler(
-            IntPtr connection,
-            IntPtr context,
-            ConnectionEvent* connectionEvent)
+#pragma warning disable CS3016
+        [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })]
+#pragma warning restore CS3016
+        private static unsafe int NativeCallback(QUIC_HANDLE* connection, void* context, QUIC_CONNECTION_EVENT* connectionEvent)
         {
-            GCHandle gcHandle = GCHandle.FromIntPtr(context);
+            GCHandle gcHandle = GCHandle.FromIntPtr((IntPtr)context);
             Debug.Assert(gcHandle.IsAllocated);
             Debug.Assert(gcHandle.Target is not null);
             var state = (State)gcHandle.Target;
 
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(state, $"{state.TraceId} Connection received event {connectionEvent->Type}");
+                NetEventSource.Info(state, $"{state.Handle} Connection received event {connectionEvent->Type}");
             }
 
             try
@@ -657,14 +657,14 @@ namespace System.Net.Quic.Implementations.MsQuic
                     case QUIC_CONNECTION_EVENT_TYPE.PEER_CERTIFICATE_RECEIVED:
                         return HandleEventPeerCertificateReceived(state, ref *connectionEvent);
                     default:
-                        return MsQuicStatusCodes.Success;
+                        return QUIC_STATUS_SUCCESS;
                 }
             }
             catch (Exception ex)
             {
                 if (NetEventSource.Log.IsEnabled())
                 {
-                    NetEventSource.Error(state, $"{state.TraceId} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}");
+                    NetEventSource.Error(state, $"{state.Handle} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}");
                 }
 
                 if (state.ConnectTcs != null)
@@ -676,11 +676,11 @@ namespace System.Net.Quic.Implementations.MsQuic
                 }
                 else
                 {
-                    Debug.Fail($"{state.TraceId} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}");
+                    Debug.Fail($"{state.Handle} Exception occurred during handling {connectionEvent->Type} connection callback: {ex}");
                 }
 
                 // TODO: trigger an exception on any outstanding async calls.
-                return MsQuicStatusCodes.InternalError;
+                return QUIC_STATUS_INTERNAL_ERROR;
             }
         }
 
@@ -712,7 +712,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        private void Dispose(bool disposing)
+        private unsafe void Dispose(bool disposing)
         {
             int disposed = Interlocked.Exchange(ref _disposed, 1);
             if (disposed != 0)
@@ -720,15 +720,15 @@ namespace System.Net.Quic.Implementations.MsQuic
                 return;
             }
 
-            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{TraceId()} Connection disposing {disposing}");
+            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{_state.Handle} Connection disposing {disposing}");
 
             // If we haven't already shutdown gracefully (via a successful CloseAsync call), then force an abortive shutdown.
             if (_state.Handle != null && !_state.Handle.IsInvalid && !_state.Handle.IsClosed)
             {
                 // Handle can be null if outbound constructor failed and we are called from finalizer.
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicApi.Api.ConnectionShutdownDelegate(
-                    _state.Handle,
+                MsQuicApi.Api.ApiTable->ConnectionShutdown(
+                    _state.Handle.QuicHandle,
                     QUIC_CONNECTION_SHUTDOWN_FLAGS.SILENT,
                     0);
             }
@@ -752,7 +752,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             _configuration?.Dispose();
             if (releaseHandles)
             {
-                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{TraceId()} Connection releasing handle");
+                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{_state.Handle} Connection releasing handle");
 
                 // We may not be fully initialized if constructor fails.
                 _state.Handle?.Dispose();
index 7c68313..8ae290b 100644 (file)
@@ -12,15 +12,15 @@ using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Channels;
 using System.Threading.Tasks;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
 using System.Net.Sockets;
+using Microsoft.Quic;
+using System.Runtime.CompilerServices;
+using static Microsoft.Quic.MsQuic;
 
 namespace System.Net.Quic.Implementations.MsQuic
 {
     internal sealed class MsQuicListener : QuicListenerProvider, IDisposable
     {
-        private static unsafe readonly ListenerCallbackDelegate s_listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler);
-
         private readonly State _state;
         private GCHandle _stateHandle;
         private volatile bool _disposed;
@@ -31,7 +31,6 @@ namespace System.Net.Quic.Implementations.MsQuic
         {
             // set immediately in ctor, but we need a GCHandle to State in order to create the handle.
             public SafeMsQuicListenerHandle Handle = null!;
-            public string TraceId = null!; // set in ctor.
 
             public TaskCompletionSource StopCompletion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
 
@@ -83,7 +82,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        internal MsQuicListener(QuicListenerOptions options)
+        internal unsafe MsQuicListener(QuicListenerOptions options)
         {
             ArgumentNullException.ThrowIfNull(options.ListenEndPoint, nameof(options.ListenEndPoint));
 
@@ -91,14 +90,14 @@ namespace System.Net.Quic.Implementations.MsQuic
             _stateHandle = GCHandle.Alloc(_state);
             try
             {
+                QUIC_HANDLE* handle;
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                uint status = MsQuicApi.Api.ListenerOpenDelegate(
-                    MsQuicApi.Api.Registration,
-                    s_listenerDelegate,
-                    GCHandle.ToIntPtr(_stateHandle),
-                    out _state.Handle);
-
-                QuicExceptionHelpers.ThrowIfFailed(status, "ListenerOpen failed.");
+                ThrowIfFailure(MsQuicApi.Api.ApiTable->ListenerOpen(
+                    MsQuicApi.Api.Registration.QuicHandle,
+                    &NativeCallback,
+                    (void*)GCHandle.ToIntPtr(_stateHandle),
+                    &handle), "ListenerOpen failed");
+                _state.Handle = new SafeMsQuicListenerHandle(handle);
             }
             catch
             {
@@ -106,17 +105,16 @@ namespace System.Net.Quic.Implementations.MsQuic
                 throw;
             }
 
-            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(_state, $"{_state.TraceId} Listener created");
+                NetEventSource.Info(_state, $"{_state.Handle} Listener created");
             }
 
             _listenEndPoint = Start(options);
 
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(_state, $"{_state.TraceId} Listener started");
+                NetEventSource.Info(_state, $"{_state.Handle} Listener started");
             }
         }
 
@@ -183,19 +181,23 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             Internals.SocketAddress address = IPEndPointExtensions.Serialize(listenEndPoint);
 
-            uint status;
-
             Debug.Assert(_stateHandle.IsAllocated);
-
-            MemoryHandle[]? handles = null;
-            QuicBuffer[]? buffers = null;
             try
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicAlpnHelper.Prepare(applicationProtocols, out handles, out buffers);
+                using var msquicBuffers = new MsQuicBuffers();
+                msquicBuffers.Initialize(applicationProtocols, applicationProtocol => applicationProtocol.Protocol);
+                // TODO: is the layout same for SocketAddress.Buffer and QuicAddr?
+                // TODO: maybe add simple extensions/helpers:
+                //       - QuicAddr ToQuicAddr(this IPEndPoint ipEndPoint)
+                //       - IPEndPoint ToIPEndPoint(this ref QuicAddr quicAddress)
                 fixed (byte* paddress = address.Buffer)
                 {
-                    status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, paddress);
+                    ThrowIfFailure(MsQuicApi.Api.ApiTable->ListenerStart(
+                        _state.Handle.QuicHandle,
+                        msquicBuffers.Buffers,
+                        (uint)applicationProtocols.Count,
+                        (QuicAddr*)paddress), "ListenerStart failed");
                 }
             }
             catch
@@ -203,18 +205,12 @@ namespace System.Net.Quic.Implementations.MsQuic
                 _stateHandle.Free();
                 throw;
             }
-            finally
-            {
-                MsQuicAlpnHelper.Return(ref handles, ref buffers);
-            }
-
-            QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");
 
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            return MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);
+            return MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS);
         }
 
-        private Task StopAsync()
+        private unsafe Task StopAsync()
         {
             // TODO finalizers are called even if the object construction fails.
             if (_state == null)
@@ -227,47 +223,47 @@ namespace System.Net.Quic.Implementations.MsQuic
             if (_state.Handle != null)
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicApi.Api.ListenerStopDelegate(_state.Handle);
+                MsQuicApi.Api.ApiTable->ListenerStop(_state.Handle.QuicHandle);
             }
             return _state.StopCompletion.Task;
         }
 
-        private static unsafe uint NativeCallbackHandler(
-            IntPtr listener,
-            IntPtr context,
-            ListenerEvent* listenerEvent)
+#pragma warning disable CS3016
+        [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })]
+#pragma warning restore CS3016
+        private static unsafe int NativeCallback(QUIC_HANDLE* listener, void* context, QUIC_LISTENER_EVENT* listenerEvent)
         {
-            GCHandle gcHandle = GCHandle.FromIntPtr(context);
+            GCHandle gcHandle = GCHandle.FromIntPtr((IntPtr)context);
             Debug.Assert(gcHandle.IsAllocated);
             Debug.Assert(gcHandle.Target is not null);
             var state = (State)gcHandle.Target;
 
 
-            if (listenerEvent->Type == QUIC_LISTENER_EVENT.STOP_COMPLETE)
+            if (listenerEvent->Type == QUIC_LISTENER_EVENT_TYPE.STOP_COMPLETE)
             {
                 state.StopCompletion.TrySetResult();
-                return MsQuicStatusCodes.Success;
+                return QUIC_STATUS_SUCCESS;
             }
 
-            if (listenerEvent->Type != QUIC_LISTENER_EVENT.NEW_CONNECTION)
+            if (listenerEvent->Type != QUIC_LISTENER_EVENT_TYPE.NEW_CONNECTION)
             {
-                return MsQuicStatusCodes.InternalError;
+                return QUIC_STATUS_INTERNAL_ERROR;
             }
 
             SafeMsQuicConnectionHandle? connectionHandle = null;
             MsQuicConnection? msQuicConnection = null;
             try
             {
-                ref NewConnectionInfo connectionInfo = ref *listenerEvent->Data.NewConnection.Info;
+                ref QUIC_NEW_CONNECTION_INFO connectionInfo = ref *listenerEvent->NEW_CONNECTION.Info;
 
-                IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(connectionInfo.LocalAddress);
-                IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(connectionInfo.RemoteAddress);
+                IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint((IntPtr)connectionInfo.LocalAddress);
+                IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint((IntPtr)connectionInfo.RemoteAddress);
 
                 string targetHost = string.Empty;   // compat with SslStream
-                if (connectionInfo.ServerNameLength > 0 && connectionInfo.ServerName != IntPtr.Zero)
+                if (connectionInfo.ServerNameLength > 0 && (IntPtr)connectionInfo.ServerName != IntPtr.Zero)
                 {
                     // TBD We should figure out what to do with international names.
-                    targetHost = Marshal.PtrToStringAnsi(connectionInfo.ServerName, connectionInfo.ServerNameLength);
+                    targetHost = Marshal.PtrToStringAnsi((IntPtr)connectionInfo.ServerName, connectionInfo.ServerNameLength);
                 }
 
                 SafeMsQuicConfigurationHandle? connectionConfiguration = state.ConnectionConfiguration;
@@ -291,25 +287,25 @@ namespace System.Net.Quic.Implementations.MsQuic
                     if (connectionConfiguration == null)
                     {
                         // We don't have safe handle yet so MsQuic will cleanup new connection.
-                        return MsQuicStatusCodes.InternalError;
+                        return QUIC_STATUS_INTERNAL_ERROR;
                     }
                 }
 
-                connectionHandle = new SafeMsQuicConnectionHandle(listenerEvent->Data.NewConnection.Connection);
+                connectionHandle = new SafeMsQuicConnectionHandle(listenerEvent->NEW_CONNECTION.Connection);
 
                 Debug.Assert(!Monitor.IsEntered(state), "!Monitor.IsEntered(state)");
-                uint status = MsQuicApi.Api.ConnectionSetConfigurationDelegate(connectionHandle, connectionConfiguration);
-                if (MsQuicStatusHelper.SuccessfulStatusCode(status))
+                int status = MsQuicApi.Api.ApiTable->ConnectionSetConfiguration(connectionHandle.QuicHandle, connectionConfiguration.QuicHandle);
+                if (StatusSucceeded(status))
                 {
                     msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, state, connectionHandle, state.AuthenticationOptions.ClientCertificateRequired, state.AuthenticationOptions.CertificateRevocationCheckMode, state.AuthenticationOptions.RemoteCertificateValidationCallback);
-                    msQuicConnection.SetNegotiatedAlpn(connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);
+                    msQuicConnection.SetNegotiatedAlpn((IntPtr)connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);
 
                     if (!state.PendingConnections.TryAdd(connectionHandle.DangerousGetHandle(), msQuicConnection))
                     {
                         msQuicConnection.Dispose();
                     }
 
-                    return MsQuicStatusCodes.Success;
+                    return QUIC_STATUS_SUCCESS;
                 }
 
                 // If we fall-through here something wrong happened.
@@ -318,14 +314,14 @@ namespace System.Net.Quic.Implementations.MsQuic
             {
                 if (NetEventSource.Log.IsEnabled())
                 {
-                    NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during handling {(QUIC_LISTENER_EVENT)listenerEvent->Type} connection callback: {ex}");
+                    NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during handling {listenerEvent->Type} connection callback: {ex}");
                 }
             }
 
             // This handle will be cleaned up by MsQuic by returning InternalError.
             connectionHandle?.SetHandleAsInvalid();
             msQuicConnection?.Dispose();
-            return MsQuicStatusCodes.InternalError;
+            return QUIC_STATUS_INTERNAL_ERROR;
         }
 
         private void ThrowIfDisposed()
index ff98028..7af82fe 100644 (file)
@@ -5,19 +5,18 @@ using System.Buffers;
 using System.Diagnostics;
 using System.IO;
 using System.Net.Quic.Implementations.MsQuic.Internal;
+using System.Runtime.CompilerServices;
 using System.Runtime.ExceptionServices;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
-using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
+using Microsoft.Quic;
+using static Microsoft.Quic.MsQuic;
 
 namespace System.Net.Quic.Implementations.MsQuic
 {
     internal sealed class MsQuicStream : QuicStreamProvider
     {
-        // Delegate that wraps the static function that will be called when receiving an event.
-        internal static unsafe readonly StreamCallbackDelegate s_streamDelegate = new StreamCallbackDelegate(NativeCallbackHandler);
-
         // The state is passed to msquic and then it's passed back by msquic to the callback handler.
         private readonly State _state = new State();
 
@@ -38,7 +37,6 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             public MsQuicStream? Stream; // roots the stream in the pinned state to prevent GC during an async read I/O.
             public MsQuicConnection.State ConnectionState = null!; // set in ctor.
-            public string TraceId = null!; // set in ctor.
 
             public ReadState ReadState;
 
@@ -46,7 +44,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             public long ReadErrorCode = -1;
 
             // filled when ReadState.BuffersAvailable:
-            public QuicBuffer[] ReceiveQuicBuffers = Array.Empty<QuicBuffer>();
+            public QUIC_BUFFER[] ReceiveQuicBuffers = Array.Empty<QUIC_BUFFER>();
             public int ReceiveQuicBuffersCount;
             public int ReceiveQuicBuffersTotalBytes;
             public bool ReceiveIsFinal;
@@ -67,7 +65,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             public int SendBufferCount;
 
             // Resettable completions to be used for multiple calls to send.
-            public readonly ResettableCompletionSource<uint> SendResettableCompletionSource = new ResettableCompletionSource<uint>();
+            public readonly ResettableCompletionSource<int> SendResettableCompletionSource = new ResettableCompletionSource<int>();
 
             public ShutdownWriteState ShutdownWriteState;
 
@@ -89,7 +87,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             public void Cleanup()
             {
-                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"{TraceId} releasing handles.");
+                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"{Handle} releasing handles.");
 
                 ShutdownState = ShutdownState.Finished;
                 CleanupSendState(this);
@@ -101,10 +99,8 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        internal string TraceId() => _state.TraceId;
-
         // inbound.
-        internal MsQuicStream(MsQuicConnection.State connectionState, SafeMsQuicStreamHandle streamHandle, QUIC_STREAM_OPEN_FLAGS flags)
+        internal unsafe MsQuicStream(MsQuicConnection.State connectionState, SafeMsQuicStreamHandle streamHandle, QUIC_STREAM_OPEN_FLAGS flags)
         {
             if (!connectionState.TryAddStream(this))
             {
@@ -129,10 +125,11 @@ namespace System.Net.Quic.Implementations.MsQuic
             try
             {
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                MsQuicApi.Api.SetCallbackHandlerDelegate(
-                    _state.Handle,
-                    s_streamDelegate,
-                    GCHandle.ToIntPtr(_state.StateGCHandle));
+                delegate* unmanaged[Cdecl]<QUIC_HANDLE*, void*, QUIC_STREAM_EVENT*, int> nativeCallback = &NativeCallback;
+                MsQuicApi.Api.ApiTable->SetCallbackHandler(
+                    _state.Handle.QuicHandle,
+                    nativeCallback,
+                    (void*)GCHandle.ToIntPtr(_state.StateGCHandle));
             }
             catch
             {
@@ -141,18 +138,17 @@ namespace System.Net.Quic.Implementations.MsQuic
                 throw;
             }
 
-            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
             if (NetEventSource.Log.IsEnabled())
             {
                 NetEventSource.Info(
                     _state,
-                    $"{TraceId()} Inbound {(flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? "uni" : "bi")}directional stream created " +
-                        $"in connection {_state.ConnectionState.TraceId}.");
+                    $"{_state.Handle} Inbound {(flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? "uni" : "bi")}directional stream created " +
+                        $"in connection {_state.ConnectionState.Handle}.");
             }
         }
 
         // outbound.
-        internal MsQuicStream(MsQuicConnection.State connectionState, QUIC_STREAM_OPEN_FLAGS flags)
+        internal unsafe MsQuicStream(MsQuicConnection.State connectionState, QUIC_STREAM_OPEN_FLAGS flags)
         {
             Debug.Assert(connectionState.Handle != null);
 
@@ -175,21 +171,23 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             try
             {
+                QUIC_HANDLE* handle;
                 Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-                uint status = MsQuicApi.Api.StreamOpenDelegate(
-                    connectionState.Handle,
+                int status = MsQuicApi.Api.ApiTable->StreamOpen(
+                    connectionState.Handle.QuicHandle,
                     flags,
-                    s_streamDelegate,
-                    GCHandle.ToIntPtr(_state.StateGCHandle),
-                    out _state.Handle);
+                    &NativeCallback,
+                    (void*)GCHandle.ToIntPtr(_state.StateGCHandle),
+                    &handle);
 
-                if (status == MsQuicStatusCodes.Aborted)
+                if (status == QUIC_STATUS_ABORTED)
                 {
                     // connection already aborted by peer, throw relevant exception
                     throw ThrowHelper.GetConnectionAbortedException(connectionState.AbortErrorCode);
                 }
 
-                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to open stream to peer.");
+                ThrowIfFailure(status, "Failed to open stream to peer");
+                _state.Handle = new SafeMsQuicStreamHandle(handle);
             }
             catch
             {
@@ -198,13 +196,12 @@ namespace System.Net.Quic.Implementations.MsQuic
                 throw;
             }
 
-            _state.TraceId = MsQuicTraceHelper.GetTraceId(_state.Handle);
             if (NetEventSource.Log.IsEnabled())
             {
                 NetEventSource.Info(
                     _state,
-                    $"{_state.TraceId} Outbound {(flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? "uni" : "bi")}directional stream created " +
-                        $"in connection {_state.ConnectionState.TraceId}.");
+                    $"{_state.Handle} Outbound {(flags.HasFlag(QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL) ? "uni" : "bi")}directional stream created " +
+                        $"in connection {_state.ConnectionState.Handle}.");
             }
         }
 
@@ -437,7 +434,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(_state, $"{TraceId()} Stream reading into Memory of '{destination.Length}' bytes.");
+                NetEventSource.Info(_state, $"{_state.Handle} Stream reading into Memory of '{destination.Length}' bytes.");
             }
 
             ReadState initialReadState;  // value before transitions
@@ -576,7 +573,7 @@ namespace System.Net.Quic.Implementations.MsQuic
         }
 
         /// <returns>The number of bytes copied.</returns>
-        private static unsafe int CopyMsQuicBuffersToUserBuffer(ReadOnlySpan<QuicBuffer> sourceBuffers, Span<byte> destinationBuffer)
+        private static unsafe int CopyMsQuicBuffersToUserBuffer(ReadOnlySpan<QUIC_BUFFER> sourceBuffers, Span<byte> destinationBuffer)
         {
             if (sourceBuffers.Length == 0)
             {
@@ -584,7 +581,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
             int originalDestinationLength = destinationBuffer.Length;
-            QuicBuffer nativeBuffer;
+            QUIC_BUFFER nativeBuffer;
             int takeLength;
             int i = 0;
 
@@ -671,11 +668,13 @@ namespace System.Net.Quic.Implementations.MsQuic
             StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.ABORT_SEND, errorCode);
         }
 
-        private void StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS flags, long errorCode)
+        private unsafe void StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS flags, long errorCode)
         {
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            uint status = MsQuicApi.Api.StreamShutdownDelegate(_state.Handle, flags, errorCode);
-            QuicExceptionHelpers.ThrowIfFailed(status, "StreamShutdown failed.");
+            ThrowIfFailure(MsQuicApi.Api.ApiTable->StreamShutdown(
+                _state.Handle.QuicHandle,
+                flags,
+                (uint)errorCode), "StreamShutdown failed");
         }
 
         internal override async ValueTask ShutdownCompleted(CancellationToken cancellationToken = default)
@@ -843,7 +842,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
 
-            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{TraceId()} Stream disposing {disposing}");
+            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{_state.Handle} Stream disposing {disposing}");
 
             bool callShutdown = false;
             bool abortRead = false;
@@ -877,24 +876,27 @@ namespace System.Net.Quic.Implementations.MsQuic
                 }
             }
 
-            if (callShutdown)
+            if (_state.Handle != null && !_state.Handle.IsInvalid && !_state.Handle.IsClosed)
             {
-                try
+                if (callShutdown)
                 {
-                    // Handle race condition when stream can be closed handling SHUTDOWN_COMPLETE.
-                    StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.GRACEFUL, errorCode: 0);
+                    try
+                    {
+                        // Handle race condition when stream can be closed handling SHUTDOWN_COMPLETE.
+                        StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.GRACEFUL, errorCode: 0);
+                    }
+                    catch (ObjectDisposedException) { };
                 }
-                catch (ObjectDisposedException) { };
-            }
 
-            if (abortRead)
-            {
-                try
+                if (abortRead)
                 {
-                    // TODO: error code used here MUST be specified by the application layer
-                    StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.ABORT_RECEIVE, 0xffffffff);
+                    try
+                    {
+                        // TODO: error code used here MUST be specified by the application layer
+                        StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.ABORT_RECEIVE, 0xffffffff);
+                    }
+                    catch (ObjectDisposedException) { };
                 }
-                catch (ObjectDisposedException) { };
             }
 
             if (completeRead)
@@ -908,33 +910,32 @@ namespace System.Net.Quic.Implementations.MsQuic
                 _state.Cleanup();
             }
 
-            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{TraceId()} Stream disposed");
+            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{_state.Handle} Stream disposed");
         }
 
-        private void EnableReceive()
+        private unsafe void EnableReceive()
         {
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            uint status = MsQuicApi.Api.StreamReceiveSetEnabledDelegate(_state.Handle, enabled: true);
-            QuicExceptionHelpers.ThrowIfFailed(status, "StreamReceiveSetEnabled failed.");
+            ThrowIfFailure(MsQuicApi.Api.ApiTable->StreamReceiveSetEnabled(_state.Handle.QuicHandle, 1), "StreamReceiveSetEnabled failed");
         }
 
         /// <summary>
         /// Callback calls for a single instance of a stream are serialized by msquic.
         /// They happen on a msquic thread and shouldn't take too long to not to block msquic.
         /// </summary>
-        private static unsafe uint NativeCallbackHandler(
-            IntPtr stream,
-            IntPtr context,
-            StreamEvent* streamEvent)
+#pragma warning disable CS3016
+        [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })]
+#pragma warning restore CS3016
+        private static unsafe int NativeCallback(QUIC_HANDLE* stream, void* context, QUIC_STREAM_EVENT* streamEvent)
         {
-            GCHandle gcHandle = GCHandle.FromIntPtr(context);
+            GCHandle gcHandle = GCHandle.FromIntPtr((IntPtr)context);
             Debug.Assert(gcHandle.IsAllocated);
             Debug.Assert(gcHandle.Target is not null);
             var state = (State)gcHandle.Target;
 
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(state, $"{state.TraceId} Stream received event {streamEvent->Type}");
+                NetEventSource.Info(state, $"{state.Handle} Stream received event {streamEvent->Type}");
             }
 
             try
@@ -973,29 +974,29 @@ namespace System.Net.Quic.Implementations.MsQuic
                     case QUIC_STREAM_EVENT_TYPE.PEER_ACCEPTED:
                         return HandleEventPeerAccepted(state);
                     default:
-                        return MsQuicStatusCodes.Success;
+                        return QUIC_STATUS_SUCCESS;
                 }
             }
             catch (Exception ex)
             {
                 if (NetEventSource.Log.IsEnabled())
                 {
-                    NetEventSource.Error(state, $"{state.TraceId} Exception occurred during handling Stream {streamEvent->Type} event: {ex}");
+                    NetEventSource.Error(state, $"{state.Handle} Exception occurred during handling Stream {streamEvent->Type} event: {ex}");
                 }
 
-                Debug.Fail($"{state.TraceId} Exception occurred during handling Stream {streamEvent->Type} event: {ex}");
+                Debug.Fail($"{state.Handle} Exception occurred during handling Stream {streamEvent->Type} event: {ex}");
 
-                return MsQuicStatusCodes.InternalError;
+                return QUIC_STATUS_INTERNAL_ERROR;
             }
         }
 
-        private static unsafe uint HandleEventReceive(State state, ref StreamEvent evt)
+        private static unsafe int HandleEventReceive(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
-            ref StreamEventDataReceive receiveEvent = ref evt.Data.Receive;
+            ref var receiveEvent = ref streamEvent.RECEIVE;
 
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(state, $"{state.TraceId} Stream received {receiveEvent.TotalBufferLength} bytes{(receiveEvent.Flags.HasFlag(QUIC_RECEIVE_FLAGS.FIN) ? " with FIN flag" : "")}");
+                NetEventSource.Info(state, $"{state.Handle} Stream received {receiveEvent.TotalBufferLength} bytes{(receiveEvent.Flags.HasFlag(QUIC_RECEIVE_FLAGS.FIN) ? " with FIN flag" : "")}");
             }
 
             int readLength;
@@ -1020,12 +1021,12 @@ namespace System.Net.Quic.Implementations.MsQuic
 
                         if ((uint)state.ReceiveQuicBuffers.Length < receiveEvent.BufferCount)
                         {
-                            QuicBuffer[] oldReceiveBuffers = state.ReceiveQuicBuffers;
-                            state.ReceiveQuicBuffers = ArrayPool<QuicBuffer>.Shared.Rent((int)receiveEvent.BufferCount);
+                            QUIC_BUFFER[] oldReceiveBuffers = state.ReceiveQuicBuffers;
+                            state.ReceiveQuicBuffers = ArrayPool<QUIC_BUFFER>.Shared.Rent((int)receiveEvent.BufferCount);
 
                             if (oldReceiveBuffers.Length != 0) // don't return Array.Empty.
                             {
-                                ArrayPool<QuicBuffer>.Shared.Return(oldReceiveBuffers);
+                                ArrayPool<QUIC_BUFFER>.Shared.Return(oldReceiveBuffers);
                             }
                         }
 
@@ -1048,13 +1049,13 @@ namespace System.Net.Quic.Implementations.MsQuic
                             }
 
                             // if it was not a graceful shutdown, we defer aborting to PEER_SEND_ABORT event handler
-                            return MsQuicStatusCodes.Success;
+                            return QUIC_STATUS_SUCCESS;
                         }
                         else
                         {
                             // Normal RECEIVE - data will be buffered until user calls ReadAsync() and no new event will be issued until EnableReceive()
                             state.ReadState = ReadState.IndividualReadComplete;
-                            return MsQuicStatusCodes.Pending;
+                            return QUIC_STATUS_PENDING;
                         }
 
                     case ReadState.PendingRead:
@@ -1066,7 +1067,7 @@ namespace System.Net.Quic.Implementations.MsQuic
                         state.ReadState = ReadState.PendingReadFinished;
                         // state.ReadState will be set to None later once the ReceiveResettableCompletionSource is awaited.
 
-                        readLength = CopyMsQuicBuffersToUserBuffer(new ReadOnlySpan<QuicBuffer>(receiveEvent.Buffers, (int)receiveEvent.BufferCount), state.ReceiveUserBuffer.Span);
+                        readLength = CopyMsQuicBuffersToUserBuffer(new ReadOnlySpan<QUIC_BUFFER>(receiveEvent.Buffers, (int)receiveEvent.BufferCount), state.ReceiveUserBuffer.Span);
 
                         // This was a final message and we've consumed everything. We can complete the state without waiting for PEER_SEND_SHUTDOWN
                         if (receiveEvent.Flags.HasFlag(QUIC_RECEIVE_FLAGS.FIN) && (uint)readLength == receiveEvent.TotalBufferLength)
@@ -1083,7 +1084,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
                         // There was a race between a user aborting the read stream and the callback being ran.
                         // This will eat any received data.
-                        return MsQuicStatusCodes.Success;
+                        return QUIC_STATUS_SUCCESS;
                 }
             }
 
@@ -1096,15 +1097,15 @@ namespace System.Net.Quic.Implementations.MsQuic
             // Returning Success when the entire buffer hasn't been consumed will cause MsQuic to disable further receive events until EnableReceive() is called.
             // Returning Continue will cause a second receive event to fire immediately after this returns, but allows MsQuic to clean up its buffers.
 
-            uint ret = (uint)readLength == receiveEvent.TotalBufferLength
-                ? MsQuicStatusCodes.Success
-                : MsQuicStatusCodes.Continue;
+            int ret = (uint)readLength == receiveEvent.TotalBufferLength
+                ? QUIC_STATUS_SUCCESS
+                : QUIC_STATUS_CONTINUE;
 
             receiveEvent.TotalBufferLength = (uint)readLength;
             return ret;
         }
 
-        private static uint HandleEventPeerRecvAborted(State state, ref StreamEvent evt)
+        private static int HandleEventPeerRecvAborted(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
             bool shouldSendComplete = false;
             bool shouldShutdownWriteComplete = false;
@@ -1122,7 +1123,7 @@ namespace System.Net.Quic.Implementations.MsQuic
                 }
 
                 state.SendState = SendState.Aborted;
-                state.SendErrorCode = (long)evt.Data.PeerReceiveAborted.ErrorCode;
+                state.SendErrorCode = (long)streamEvent.PEER_RECEIVE_ABORTED.ErrorCode;
             }
 
             if (shouldSendComplete)
@@ -1137,26 +1138,26 @@ namespace System.Net.Quic.Implementations.MsQuic
                     ExceptionDispatchInfo.SetCurrentStackTrace(new QuicStreamAbortedException(state.SendErrorCode)));
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventStartComplete(State state, ref StreamEvent evt)
+        private static int HandleEventStartComplete(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
-            uint status = evt.Data.StartComplete.Status;
+            int status = streamEvent.START_COMPLETE.Status;
 
             // The way we expose Open(Uni|Bi)directionalStreamAsync operations is that the stream
             // is also accepted by the peer (i.e. it is within advertised stream limits). However,
             // We may receive START_COMPLETE notification before the stream is accepted, so we defer
             // completing the StartcompletionSource until we get PeerAccepted notification.
 
-            if (status != MsQuicStatusCodes.Success)
+            if (status != QUIC_STATUS_SUCCESS)
             {
                 // Start irrecoverably failed. The possible status codes are:
                 //   - Aborted - connection aborted by peer
                 //   - InvalidState - stream already started before, or connection aborted locally
                 //   - StreamLimitReached - only if QUIC_STREAM_START_FLAG_FAIL_BLOCKED was specified (not in our case).
                 //
-                if (status == MsQuicStatusCodes.Aborted)
+                if (status == QUIC_STATUS_ABORTED)
                 {
                     state.StartCompletionSource.TrySetException(
                         ExceptionDispatchInfo.SetCurrentStackTrace(GetConnectionAbortedException(state)));
@@ -1166,10 +1167,10 @@ namespace System.Net.Quic.Implementations.MsQuic
                     // TODO: Should we throw QuicOperationAbortedException when status is InvalidState?
                     // [ActiveIssue("https://github.com/dotnet/runtime/issues/55619")]
                     state.StartCompletionSource.TrySetException(
-                        ExceptionDispatchInfo.SetCurrentStackTrace(new QuicException($"StreamStart finished with status {MsQuicStatusCodes.GetError(status)}")));
+                        ExceptionDispatchInfo.SetCurrentStackTrace(new MsQuicException(status, "StreamStart failed")));
                 }
             }
-            else if ((evt.Data.StartComplete.PeerAccepted & 1) != 0)
+            else if ((streamEvent.START_COMPLETE.PeerAccepted & 1) != 0)
             {
                 // Start succeeded and we were within stream limits, stream already usable.
                 state.StartCompletionSource.TrySetResult();
@@ -1177,10 +1178,10 @@ namespace System.Net.Quic.Implementations.MsQuic
             // if PeerAccepted == 0, we will later receive PEER_ACCEPTED event, which will
             // complete the StartCompletionSource
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventSendShutdownComplete(State state, ref StreamEvent evt)
+        private static int HandleEventSendShutdownComplete(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
             // Graceful will be false in three situations:
             // 1. The peer aborted reads and the PEER_RECEIVE_ABORTED event was raised.
@@ -1191,7 +1192,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             //    SHUTDOWN_COMPLETE event will be raised immediately after this event. It will handle completing with an error.
             //
             // Only use this event with sends gracefully completed.
-            if (evt.Data.SendShutdownComplete.Graceful != 0)
+            if (streamEvent.SEND_SHUTDOWN_COMPLETE.Graceful != 0)
             {
                 bool shouldComplete = false;
                 lock (state)
@@ -1209,12 +1210,12 @@ namespace System.Net.Quic.Implementations.MsQuic
                 }
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventShutdownComplete(State state, ref StreamEvent evt)
+        private static int HandleEventShutdownComplete(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
-            StreamEventDataShutdownComplete shutdownCompleteEvent = evt.Data.ShutdownComplete;
+            var shutdownCompleteEvent = streamEvent.SHUTDOWN_COMPLETE;
 
             if (shutdownCompleteEvent.ConnectionShutdown != 0)
             {
@@ -1228,7 +1229,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             lock (state)
             {
                 // This event won't occur within the middle of a receive.
-                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(state, $"{state.TraceId} Stream completing resettable event source.");
+                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(state, $"{state.Handle} Stream completing resettable event source.");
 
                 shouldReadComplete = CleanupReadStateAndCheckPending(state, ReadState.ReadsCompleted);
 
@@ -1290,22 +1291,22 @@ namespace System.Net.Quic.Implementations.MsQuic
                 state.Cleanup();
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventPeerAccepted(State state)
+        private static int HandleEventPeerAccepted(State state)
         {
             state.StartCompletionSource.TrySetResult();
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventPeerSendAborted(State state, ref StreamEvent evt)
+        private static int HandleEventPeerSendAborted(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
             bool shouldComplete = false;
             lock (state)
             {
                 shouldComplete = CleanupReadStateAndCheckPending(state, ReadState.Aborted);
-                state.ReadErrorCode = (long)evt.Data.PeerSendAborted.ErrorCode;
+                state.ReadErrorCode = (long)streamEvent.PEER_SEND_ABORTED.ErrorCode;
             }
 
             if (shouldComplete)
@@ -1314,17 +1315,17 @@ namespace System.Net.Quic.Implementations.MsQuic
                     ExceptionDispatchInfo.SetCurrentStackTrace(new QuicStreamAbortedException(state.ReadErrorCode)));
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventPeerSendShutdown(State state)
+        private static int HandleEventPeerSendShutdown(State state)
         {
             bool shouldComplete = false;
 
             lock (state)
             {
                 // This event won't occur within the middle of a receive.
-                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(state, $"{state.TraceId} Stream completing resettable event source.");
+                if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(state, $"{state.Handle} Stream completing resettable event source.");
 
                 shouldComplete = CleanupReadStateAndCheckPending(state, ReadState.ReadsCompleted);
             }
@@ -1334,12 +1335,12 @@ namespace System.Net.Quic.Implementations.MsQuic
                 state.ReceiveResettableCompletionSource.Complete(0);
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
-        private static uint HandleEventSendComplete(State state, ref StreamEvent evt)
+        private static int HandleEventSendComplete(State state, ref QUIC_STREAM_EVENT streamEvent)
         {
-            StreamEventDataSendComplete sendCompleteEvent = evt.Data.SendComplete;
+            var sendCompleteEvent = streamEvent.SEND_COMPLETE;
             bool canceled = sendCompleteEvent.Canceled != 0;
 
             bool complete = false;
@@ -1364,7 +1365,7 @@ namespace System.Net.Quic.Implementations.MsQuic
 
                 if (!canceled)
                 {
-                    state.SendResettableCompletionSource.Complete(MsQuicStatusCodes.Success);
+                    state.SendResettableCompletionSource.Complete(QUIC_STATUS_SUCCESS);
                 }
                 else
                 {
@@ -1381,7 +1382,7 @@ namespace System.Net.Quic.Implementations.MsQuic
                 }
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
         private static void CleanupSendState(State state)
@@ -1416,11 +1417,11 @@ namespace System.Net.Quic.Implementations.MsQuic
             MemoryHandle handle = buffer.Pin();
             if (_state.SendQuicBuffers == IntPtr.Zero)
             {
-                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QuicBuffer));
+                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QUIC_BUFFER));
                 _state.SendBufferMaxCount = 1;
             }
 
-            QuicBuffer* quicBuffers = (QuicBuffer*)_state.SendQuicBuffers;
+            QUIC_BUFFER* quicBuffers = (QUIC_BUFFER*)_state.SendQuicBuffers;
             quicBuffers->Length = (uint)buffer.Length;
             quicBuffers->Buffer = (byte*)handle.Pointer;
 
@@ -1428,24 +1429,23 @@ namespace System.Net.Quic.Implementations.MsQuic
             _state.SendBufferCount = 1;
 
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            uint status = MsQuicApi.Api.StreamSendDelegate(
-                _state.Handle,
+            int status = MsQuicApi.Api.ApiTable->StreamSend(
+                _state.Handle.QuicHandle,
                 quicBuffers,
-                bufferCount: 1,
+                1,
                 flags,
-                IntPtr.Zero);
+                (void*)IntPtr.Zero);
 
-            if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
+            if (!StatusSucceeded(status))
             {
                 CleanupWriteFailedState();
                 CleanupSendState(_state);
 
-                if (status == MsQuicStatusCodes.Aborted)
+                if (status == QUIC_STATUS_ABORTED)
                 {
                     throw ThrowHelper.GetConnectionAbortedException(_state.ConnectionState.AbortErrorCode);
                 }
-                QuicExceptionHelpers.ThrowIfFailed(status,
-                    "Could not send data to peer.");
+                ThrowIfFailure(status, "Could not send data to peer");
             }
 
             return _state.SendResettableCompletionSource.GetTypelessValueTask();
@@ -1476,7 +1476,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             {
                 Marshal.FreeHGlobal(_state.SendQuicBuffers);
                 _state.SendQuicBuffers = IntPtr.Zero;
-                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QuicBuffer) * count);
+                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QUIC_BUFFER) * count);
                 _state.SendBufferMaxCount = count;
                 _state.BufferArrays = new MemoryHandle[count];
             }
@@ -1484,7 +1484,7 @@ namespace System.Net.Quic.Implementations.MsQuic
             _state.SendBufferCount = count;
             count = 0;
 
-            QuicBuffer* quicBuffers = (QuicBuffer*)_state.SendQuicBuffers;
+            QUIC_BUFFER* quicBuffers = (QUIC_BUFFER*)_state.SendQuicBuffers;
             foreach (ReadOnlyMemory<byte> buffer in buffers)
             {
                 MemoryHandle handle = buffer.Pin();
@@ -1495,24 +1495,23 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            uint status = MsQuicApi.Api.StreamSendDelegate(
-                _state.Handle,
+            int status = MsQuicApi.Api.ApiTable->StreamSend(
+                _state.Handle.QuicHandle,
                 quicBuffers,
                 (uint)count,
                 flags,
-                IntPtr.Zero);
+                (void*)IntPtr.Zero);
 
-            if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
+            if (!StatusSucceeded(status))
             {
                 CleanupWriteFailedState();
                 CleanupSendState(_state);
 
-                if (status == MsQuicStatusCodes.Aborted)
+                if (status == QUIC_STATUS_ABORTED)
                 {
                     throw ThrowHelper.GetConnectionAbortedException(_state.ConnectionState.AbortErrorCode);
                 }
-                QuicExceptionHelpers.ThrowIfFailed(status,
-                    "Could not send data to peer.");
+                ThrowIfFailure(status, "Could not send data to peer");
             }
 
             return _state.SendResettableCompletionSource.GetTypelessValueTask();
@@ -1540,13 +1539,13 @@ namespace System.Net.Quic.Implementations.MsQuic
             {
                 Marshal.FreeHGlobal(_state.SendQuicBuffers);
                 _state.SendQuicBuffers = IntPtr.Zero;
-                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QuicBuffer) * array.Length);
+                _state.SendQuicBuffers = Marshal.AllocHGlobal(sizeof(QUIC_BUFFER) * array.Length);
                 _state.SendBufferMaxCount = array.Length;
                 _state.BufferArrays = new MemoryHandle[array.Length];
             }
 
             _state.SendBufferCount = array.Length;
-            QuicBuffer* quicBuffers = (QuicBuffer*)_state.SendQuicBuffers;
+            QUIC_BUFFER* quicBuffers = (QUIC_BUFFER*)_state.SendQuicBuffers;
             for (int i = 0; i < length; i++)
             {
                 ReadOnlyMemory<byte> buffer = array[i];
@@ -1559,39 +1558,38 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
 
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            uint status = MsQuicApi.Api.StreamSendDelegate(
-                _state.Handle,
+            int status = MsQuicApi.Api.ApiTable->StreamSend(
+                _state.Handle.QuicHandle,
                 quicBuffers,
                 length,
                 flags,
-                IntPtr.Zero);
+                (void*)IntPtr.Zero);
 
-            if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
+            if (!StatusSucceeded(status))
             {
                 CleanupWriteFailedState();
                 CleanupSendState(_state);
 
-                if (status == MsQuicStatusCodes.Aborted)
+                if (status == QUIC_STATUS_ABORTED)
                 {
                     throw ThrowHelper.GetConnectionAbortedException(_state.ConnectionState.AbortErrorCode);
                 }
-                QuicExceptionHelpers.ThrowIfFailed(status,
-                    "Could not send data to peer.");
+                ThrowIfFailure(status, "Could not send data to peer");
             }
 
             return _state.SendResettableCompletionSource.GetTypelessValueTask();
         }
 
-        private void ReceiveComplete(int bufferLength)
+        private unsafe void ReceiveComplete(int bufferLength)
         {
             Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
-            MsQuicApi.Api.StreamReceiveCompleteDelegate(_state.Handle, (ulong)bufferLength);
+            MsQuicApi.Api.ApiTable->StreamReceiveComplete(_state.Handle.QuicHandle, (ulong)bufferLength);
         }
 
         // This can fail if the stream isn't started.
         private long GetStreamId()
         {
-            return (long)MsQuicParameterHelpers.GetULongParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_STREAM.ID);
+            return (long)MsQuicParameterHelpers.GetULongParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_STREAM_ID);
         }
 
         private void ThrowIfDisposed()
@@ -1602,12 +1600,12 @@ namespace System.Net.Quic.Implementations.MsQuic
             }
         }
 
-        private static uint HandleEventConnectionClose(State state)
+        private static int HandleEventConnectionClose(State state)
         {
             long errorCode = state.ConnectionState.AbortErrorCode;
             if (NetEventSource.Log.IsEnabled())
             {
-                NetEventSource.Info(state, $"{state.TraceId} Stream handling connection {state.ConnectionState.TraceId} close" +
+                NetEventSource.Info(state, $"{state.Handle} Stream handling connection {state.ConnectionState.Handle} close" +
                     (errorCode != -1 ? $" with code {errorCode}" : ""));
             }
 
@@ -1676,7 +1674,7 @@ namespace System.Net.Quic.Implementations.MsQuic
                 state.Cleanup();
             }
 
-            return MsQuicStatusCodes.Success;
+            return QUIC_STATUS_SUCCESS;
         }
 
         private static Exception GetConnectionAbortedException(State state) =>
@@ -1711,12 +1709,19 @@ namespace System.Net.Quic.Implementations.MsQuic
                 ((State)state!).StartCompletionSource.TrySetCanceled(token);
             }, _state);
 
-            uint status = MsQuicApi.Api.StreamStartDelegate(_state.Handle, QUIC_STREAM_START_FLAGS.SHUTDOWN_ON_FAIL | QUIC_STREAM_START_FLAGS.INDICATE_PEER_ACCEPT);
+            int status;
+            unsafe
+            {
+                status = MsQuicApi.Api.ApiTable->StreamStart(
+                    _state.Handle.QuicHandle,
+                    QUIC_STREAM_START_FLAGS.SHUTDOWN_ON_FAIL | QUIC_STREAM_START_FLAGS.INDICATE_PEER_ACCEPT);
+            }
 
-            if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
+            if (!StatusSucceeded(status))
             {
-                _state.StartCompletionSource.TrySetException(QuicExceptionHelpers.CreateExceptionForHResult(status, "Could not start stream."));
-                throw QuicExceptionHelpers.CreateExceptionForHResult(status, "Could not start stream.");
+                Exception exception = new MsQuicException(status, "Could not start stream");
+                _state.StartCompletionSource.TrySetException(ExceptionDispatchInfo.SetCurrentStackTrace(exception));
+                throw exception;
             }
 
             await _state.StartCompletionSource.Task.ConfigureAwait(false);
index 66d66f0..a848475 100644 (file)
@@ -2,11 +2,20 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Diagnostics.Tracing;
+using System.Net.Quic.Implementations.MsQuic.Internal;
 
 namespace System.Net
 {
     [EventSource(Name = "Private.InternalDiagnostics.System.Net.Quic")]
     internal sealed partial class NetEventSource : EventSource
     {
+        static partial void AdditionalCustomizedToString<T>(T value, ref string? result)
+        {
+            MsQuicSafeHandle? safeHandle = value as MsQuicSafeHandle;
+            if (safeHandle is not null)
+            {
+                result = safeHandle.ToString();
+            }
+        }
     }
 }
index 4cd9745..151eb54 100644 (file)
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
 namespace System.Net.Quic
@@ -17,7 +17,12 @@ namespace System.Net.Quic
         public QuicException(string? message, Exception? innerException, int result)
             : base(message, innerException)
         {
-            HResult = result;
+            // HResult 0 means OK, so do not override the default value set by Exception ctor,
+            // because in this case we don't have an HResult.
+            if (result != 0)
+            {
+                HResult = result;
+            }
         }
     }
 }
index 17793a6..aa7eaa6 100644 (file)
@@ -56,7 +56,7 @@ namespace System.Net.Quic.Tests
         [Fact]
         public async Task MismatchedCipherPolicies_ConnectAsync_ThrowsQuicException()
         {
-            await Assert.ThrowsAsync<QuicException>(() => TestConnection(
+            await Assert.ThrowsAnyAsync<QuicException>(() => TestConnection(
                new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_128_GCM_SHA256 }),
                new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_256_GCM_SHA384 })
             ));
index 0baa8dc..a69f69a 100644 (file)
@@ -146,7 +146,6 @@ namespace System.Net.Quic.Tests
         }
 
         [Fact]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
         public async Task CertificateCallbackThrowPropagates()
         {
             using CancellationTokenSource cts = new CancellationTokenSource(PassingTestTimeout);
@@ -188,7 +187,6 @@ namespace System.Net.Quic.Tests
         }
 
         [Fact]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
         public async Task ConnectWithCertificateCallback()
         {
             X509Certificate2 c1 = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate();
@@ -239,7 +237,7 @@ namespace System.Net.Quic.Tests
             clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, clientOptions);
             Task clientTask = clientConnection.ConnectAsync(cts.Token).AsTask();
 
-            await Assert.ThrowsAsync<QuicException>(() => clientTask);
+            await Assert.ThrowsAnyAsync<QuicException>(() => clientTask);
             Assert.Equal(clientOptions.ClientAuthenticationOptions.TargetHost, receivedHostName);
             clientConnection.Dispose();
 
@@ -319,12 +317,6 @@ namespace System.Net.Quic.Tests
         {
             var ipAddress = IPAddress.Parse(ipString);
 
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
-            {
-                // [ActiveIssue("https://github.com/dotnet/runtime/issues/67301")]
-                throw new SkipTestException("IPv6 on Linux is temporarily broken");
-            }
-
             (X509Certificate2 certificate, _) = System.Net.Security.Tests.TestHelper.GenerateCertificates(expectsError ? "badhost" : "localhost");
 
             var listenerOptions = new QuicListenerOptions();
index 644245d..411b5d3 100644 (file)
@@ -90,7 +90,7 @@ namespace System.Net.Quic.Tests
                     else
                     {
                         await Assert.ThrowsAsync<QuicOperationAbortedException>(async () => await serverConnection.AcceptStreamAsync());
-                        await Assert.ThrowsAsync<QuicException>(() => OpenAndUseStreamAsync(serverConnection));
+                        await Assert.ThrowsAnyAsync<QuicException>(() => OpenAndUseStreamAsync(serverConnection));
                     }
                 });
         }
index bacc79b..e7586a3 100644 (file)
@@ -28,7 +28,6 @@ namespace System.Net.Quic.Tests
         }
 
         [Fact]
-        [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
         public async Task Listener_Backlog_Success_IPv6()
         {
             await Task.Run(async () =>
index e6a7a12..7f4e03a 100644 (file)
@@ -812,7 +812,7 @@ namespace System.Net.Quic.Tests
                 },
                 async serverStream =>
                 {
-                    // It may happen, that the WriteAsync call finishes early (before the AbortWrite 
+                    // It may happen, that the WriteAsync call finishes early (before the AbortWrite
                     // below), and we hit a check on the next iteration of the WriteForever.
                     // But in most cases it will still exercise aborting the outstanding write task.