From 105c3090ab11986d47d354ac1d61eaab15851659 Mon Sep 17 00:00:00 2001 From: Thad House Date: Fri, 28 May 2021 12:52:07 -0700 Subject: [PATCH] Add workaround for Kernel Mode builds using wrong CRT (#1656) * Add workaround for Kernel Mode builds using wrong CRT * Fix annotations in kernel mode new and delte * Fix user mode builds --- src/inc/msquic.hpp | 10 ++++++++-- src/inc/quic_platform.h | 7 +++++++ src/perf/bin/drvmain.cpp | 12 ++---------- src/perf/lib/PerfServer.cpp | 6 +++--- src/perf/lib/Tcp.cpp | 4 ++-- src/perf/lib/ThroughputClient.cpp | 8 ++++---- src/test/bin/quic_gtest.cpp | 2 +- src/test/bin/winkernel/control.cpp | 3 ++- src/test/bin/winkernel/driver.cpp | 14 +++----------- src/test/lib/DataTest.cpp | 6 +++--- 10 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/inc/msquic.hpp b/src/inc/msquic.hpp index 7421a4a18..f46416dab 100644 --- a/src/inc/msquic.hpp +++ b/src/inc/msquic.hpp @@ -21,6 +21,11 @@ Supported Platforms: #pragma once #include +#ifdef _KERNEL_MODE +#include +#else +#include +#endif #ifndef CXPLAT_DBG_ASSERT #define CXPLAT_DBG_ASSERT(X) // no-op if not already defined @@ -714,7 +719,7 @@ private: auto pThis = (MsQuicAutoAcceptListener*)Context; CXPLAT_DBG_ASSERT(pThis); QUIC_STATUS Status = QUIC_STATUS_INVALID_STATE; if (Event->Type == QUIC_LISTENER_EVENT_NEW_CONNECTION) { - auto Connection = new MsQuicConnection(Event->NEW_CONNECTION.Connection, CleanUpAutoDelete, pThis->ConnectionHandler, pThis->ConnectionContext); + auto Connection = new(std::nothrow) MsQuicConnection(Event->NEW_CONNECTION.Connection, CleanUpAutoDelete, pThis->ConnectionHandler, pThis->ConnectionContext); if (Connection) { Status = Connection->SetConfiguration(pThis->Configuration); if (QUIC_FAILED(Status)) { @@ -901,7 +906,8 @@ struct ConfigurationScope { struct QuicBufferScope { QUIC_BUFFER* Buffer; QuicBufferScope() noexcept : Buffer(nullptr) { } - QuicBufferScope(uint32_t Size) noexcept : Buffer((QUIC_BUFFER*) new uint8_t[sizeof(QUIC_BUFFER) + Size]) { + QuicBufferScope(uint32_t Size) noexcept : Buffer((QUIC_BUFFER*) new(std::nothrow) uint8_t[sizeof(QUIC_BUFFER) + Size]) { + CXPLAT_DBG_ASSERT(Buffer); memset(Buffer, 0, sizeof(*Buffer) + Size); Buffer->Length = Size; Buffer->Buffer = (uint8_t*)(Buffer + 1); diff --git a/src/inc/quic_platform.h b/src/inc/quic_platform.h index d87710c4d..f237c746c 100644 --- a/src/inc/quic_platform.h +++ b/src/inc/quic_platform.h @@ -17,6 +17,13 @@ Supported Environments: #pragma once +// +// Due to a bug in VS 16.10, we need to disable stdio inlining +// Remove this once that bug is fixed +// +#ifdef _KERNEL_MODE +#define _NO_CRT_STDIO_INLINE +#endif #include #define IS_POWER_OF_TWO(x) (((x) != 0) && (((x) & ((x) - 1)) == 0)) diff --git a/src/perf/bin/drvmain.cpp b/src/perf/bin/drvmain.cpp index e68c829ec..0f8d434aa 100644 --- a/src/perf/bin/drvmain.cpp +++ b/src/perf/bin/drvmain.cpp @@ -74,16 +74,12 @@ SecNetPerfCtlUninitialize( void ); -void* __cdecl operator new (size_t Size) { - return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_PERF); -} - _Ret_maybenull_ _Post_writable_byte_size_(_Size) void* __cdecl operator new (size_t Size, const std::nothrow_t&) throw(){ return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_PERF); } -void __cdecl operator delete (_In_opt_ void* Mem) { +void __cdecl operator delete (/*_In_opt_*/ void* Mem) { if (Mem != nullptr) { ExFreePoolWithTag(Mem, QUIC_POOL_PERF); } @@ -95,16 +91,12 @@ void __cdecl operator delete (_In_opt_ void* Mem, _In_opt_ size_t) { } } -void* __cdecl operator new[] (size_t Size) { - return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_PERF); -} - _Ret_maybenull_ _Post_writable_byte_size_(_Size) void* __cdecl operator new[] (size_t Size, const std::nothrow_t&) throw(){ return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_PERF); } -void __cdecl operator delete[] (_In_opt_ void* Mem) { +void __cdecl operator delete[] (/*_In_opt_*/ void* Mem) { if (Mem != nullptr) { ExFreePoolWithTag(Mem, QUIC_POOL_PERF); } diff --git a/src/perf/lib/PerfServer.cpp b/src/perf/lib/PerfServer.cpp index 9bdaeeb94..2a9ec29ac 100644 --- a/src/perf/lib/PerfServer.cpp +++ b/src/perf/lib/PerfServer.cpp @@ -267,7 +267,7 @@ PerfServer::SendTcpResponse( uint64_t BytesLeftToSend = Context->ResponseSize - Context->BytesSent; - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = (uint32_t)Context->Entry.Signature; SendData->Open = Context->BytesSent == 0 ? 1 : 0; SendData->Buffer = DataBuffer->Buffer; @@ -345,7 +345,7 @@ PerfServer::TcpReceiveCallback( } if (Abort) { Stream->ResponseSize = 0; // Reset to make sure we stop sending more - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = StreamID; SendData->Open = Open ? TRUE : FALSE; SendData->Abort = TRUE; @@ -357,7 +357,7 @@ PerfServer::TcpReceiveCallback( if (Stream->ResponseSizeSet && Stream->ResponseSize != 0) { This->SendTcpResponse(Stream, Connection); } else { - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = StreamID; SendData->Open = TRUE; SendData->Fin = TRUE; diff --git a/src/perf/lib/Tcp.cpp b/src/perf/lib/Tcp.cpp index 5917cfbf6..3bf94ce88 100644 --- a/src/perf/lib/Tcp.cpp +++ b/src/perf/lib/Tcp.cpp @@ -102,7 +102,7 @@ TcpEngine::TcpEngine( TcpConnectHandler ConnectHandler, TcpReceiveHandler ReceiveHandler, TcpSendCompleteHandler SendCompleteHandler) : - ProcCount((uint16_t)CxPlatProcActiveCount()), Workers(new TcpWorker[ProcCount]), + ProcCount((uint16_t)CxPlatProcActiveCount()), Workers(new(std::nothrow) TcpWorker[ProcCount]), AcceptHandler(AcceptHandler), ConnectHandler(ConnectHandler), ReceiveHandler(ReceiveHandler), SendCompleteHandler(SendCompleteHandler) { @@ -283,7 +283,7 @@ TcpServer::AcceptCallback( ) { auto This = (TcpServer*)ListenerContext; - auto Connection = new TcpConnection(This->Engine, This->SecConfig, AcceptSocket); + auto Connection = new(std::nothrow) TcpConnection(This->Engine, This->SecConfig, AcceptSocket); Connection->Context = This; *AcceptClientContext = Connection; } diff --git a/src/perf/lib/ThroughputClient.cpp b/src/perf/lib/ThroughputClient.cpp index 777eae2af..2c6b82040 100644 --- a/src/perf/lib/ThroughputClient.cpp +++ b/src/perf/lib/ThroughputClient.cpp @@ -392,7 +392,7 @@ ThroughputClient::StartTcp() { MsQuicCredentialConfig CredConfig(QUIC_CREDENTIAL_FLAG_CLIENT | QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION); TcpConn = - new TcpConnection( + new(std::nothrow) TcpConnection( &Engine, &CredConfig, RemoteFamily, @@ -412,7 +412,7 @@ ThroughputClient::StartTcp() TcpStrmContext->IdealSendBuffer = 1; // TCP uses send buffering, so just set to 1. if (DownloadLength) { - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = 0; SendData->Open = TRUE; SendData->Fin = TRUE; @@ -438,7 +438,7 @@ ThroughputClient::SendTcpData( uint64_t BytesLeftToSend = TimedTransfer ? UINT64_MAX : (UploadLength - Context->BytesSent); - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = 0; SendData->Open = Context->BytesSent == 0 ? TRUE : FALSE; SendData->Buffer = DataBuffer->Buffer; @@ -619,7 +619,7 @@ ThroughputClient::TcpReceiveCallback( StrmContext->BytesCompleted += Length; if (This->TimedTransfer) { if (CxPlatTimeDiff64(StrmContext->StartTime, CxPlatTimeUs64()) >= MS_TO_US(This->DownloadLength)) { - auto SendData = new TcpSendData(); + auto SendData = new(std::nothrow) TcpSendData(); SendData->StreamId = 0; SendData->Abort = TRUE; SendData->Buffer = This->DataBuffer->Buffer; diff --git a/src/test/bin/quic_gtest.cpp b/src/test/bin/quic_gtest.cpp index cc30c380a..799f43e04 100644 --- a/src/test/bin/quic_gtest.cpp +++ b/src/test/bin/quic_gtest.cpp @@ -69,7 +69,7 @@ public: ASSERT_TRUE(DriverClient.Initialize(&CertParams, DriverName)); } else { printf("Initializing for User Mode tests\n"); - MsQuic = new MsQuicApi(); + MsQuic = new(std::nothrow) MsQuicApi(); ASSERT_TRUE(QUIC_SUCCEEDED(MsQuic->GetInitStatus())); memcpy(&ServerSelfSignedCredConfig, SelfSignedCertParams, sizeof(QUIC_CREDENTIAL_CONFIG)); memcpy(&ServerSelfSignedCredConfigClientAuth, SelfSignedCertParams, sizeof(QUIC_CREDENTIAL_CONFIG)); diff --git a/src/test/bin/winkernel/control.cpp b/src/test/bin/winkernel/control.cpp index a71a15c4e..c09741326 100644 --- a/src/test/bin/winkernel/control.cpp +++ b/src/test/bin/winkernel/control.cpp @@ -11,6 +11,7 @@ Abstract: #include #include +#include #include "quic_trace.h" #ifdef QUIC_CLOG @@ -79,7 +80,7 @@ QuicTestCtlInitialize( WDF_IO_QUEUE_CONFIG QueueConfig; WDFQUEUE Queue; - MsQuic = new MsQuicApi(); + MsQuic = new (std::nothrow) MsQuicApi(); if (!MsQuic) { goto Error; } diff --git a/src/test/bin/winkernel/driver.cpp b/src/test/bin/winkernel/driver.cpp index 242bf35c7..238642688 100644 --- a/src/test/bin/winkernel/driver.cpp +++ b/src/test/bin/winkernel/driver.cpp @@ -32,37 +32,29 @@ VOID QuicTestCtlUninitialize( ); -void* __cdecl operator new (size_t Size) { - return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_TEST); -} - _Ret_maybenull_ _Post_writable_byte_size_(_Size) void* __cdecl operator new (size_t Size, const std::nothrow_t&) throw(){ return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_TEST); } -void __cdecl operator delete (_In_opt_ void* Mem) { +void __cdecl operator delete (/*_In_opt_*/ void* Mem) noexcept { if (Mem != nullptr) { ExFreePoolWithTag(Mem, QUIC_POOL_TEST); } } -void __cdecl operator delete (_In_opt_ void* Mem, _In_opt_ size_t) { +void __cdecl operator delete (_In_opt_ void* Mem, _In_opt_ size_t) noexcept { if (Mem != nullptr) { ExFreePoolWithTag(Mem, QUIC_POOL_TEST); } } -void* __cdecl operator new[] (size_t Size) { - return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_TEST); -} - _Ret_maybenull_ _Post_writable_byte_size_(_Size) void* __cdecl operator new[] (size_t Size, const std::nothrow_t&) throw(){ return ExAllocatePool2(POOL_FLAG_NON_PAGED, Size, QUIC_POOL_TEST); } -void __cdecl operator delete[] (_In_opt_ void* Mem) { +void __cdecl operator delete[] (/*_In_opt_*/ void* Mem) { if (Mem != nullptr) { ExFreePoolWithTag(Mem, QUIC_POOL_TEST); } diff --git a/src/test/lib/DataTest.cpp b/src/test/lib/DataTest.cpp index 1fc454052..415aa8001 100644 --- a/src/test/lib/DataTest.cpp +++ b/src/test/lib/DataTest.cpp @@ -2101,7 +2101,7 @@ AbortRecvConnCallback( { auto TestContext = (AbortRecvTestContext*)Context; if (Event->Type == QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED) { - TestContext->ServerStream = new MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, AbortRecvStreamCallback, Context); + TestContext->ServerStream = new(std::nothrow) MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, AbortRecvStreamCallback, Context); if (TestContext->Type == QUIC_ABORT_RECEIVE_INCOMPLETE) { TestContext->ServerStreamRecv.Set(); } @@ -2172,7 +2172,7 @@ struct SlowRecvTestContext { static QUIC_STATUS ConnCallback(_In_ MsQuicConnection*, _In_opt_ void* Context, _Inout_ QUIC_CONNECTION_EVENT* Event) { auto TestContext = (SlowRecvTestContext*)Context; if (Event->Type == QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED) { - TestContext->ServerStream = new MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, StreamCallback, Context); + TestContext->ServerStream = new(std::nothrow) MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, StreamCallback, Context); } return QUIC_STATUS_SUCCESS; } @@ -2261,7 +2261,7 @@ struct NthAllocFailTestContext { static QUIC_STATUS ConnCallback(_In_ MsQuicConnection*, _In_opt_ void* Context, _Inout_ QUIC_CONNECTION_EVENT* Event) { auto TestContext = (NthAllocFailTestContext*)Context; if (Event->Type == QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED) { - TestContext->ServerStream = new MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, StreamCallback, Context); + TestContext->ServerStream = new(std::nothrow) MsQuicStream(Event->PEER_STREAM_STARTED.Stream, CleanUpAutoDelete, StreamCallback, Context); } return QUIC_STATUS_SUCCESS; }