From 5123850db075b69272700b32314dc9b04e0b43b3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 28 Mar 2021 13:34:57 +0100 Subject: [PATCH] Fix Windows XP to 7 compatibility (#5167) * Partially reverts 01a4e696b * Unify thread names - Remove use of GetThreadId API --- Tools/MCADefrag/MCADefrag.cpp | 2 +- src/ChunkGeneratorThread.cpp | 2 +- src/ChunkSender.cpp | 2 +- src/DeadlockDetect.cpp | 2 +- src/Globals.h | 12 ++-- src/LightingThread.cpp | 2 +- src/OSSupport/IsThread.cpp | 82 ++++++++++++---------------- src/OSSupport/IsThread.h | 2 +- src/OSSupport/NetworkLookup.cpp | 2 +- src/Protocol/Authenticator.cpp | 2 +- src/Protocol/MojangAPI.cpp | 2 +- src/Root.cpp | 1 - src/Server.cpp | 2 +- src/World.cpp | 2 +- src/WorldStorage/WorldStorage.cpp | 2 +- src/mbedTLS++/AesCfb128Decryptor.cpp | 8 +-- src/mbedTLS++/AesCfb128Decryptor.h | 4 +- 17 files changed, 60 insertions(+), 71 deletions(-) diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp index d11505d45..544d9f9e8 100644 --- a/Tools/MCADefrag/MCADefrag.cpp +++ b/Tools/MCADefrag/MCADefrag.cpp @@ -126,7 +126,7 @@ AString cMCADefrag::GetNextFileName(void) // cMCADefrag::cThread: cMCADefrag::cThread::cThread(cMCADefrag & a_Parent) : - super("MCADefrag thread"), + super("MCA Defragmentor"), m_Parent(a_Parent), m_IsChunkUncompressed(false), m_Compressor(12) // Set the highest compression factor diff --git a/src/ChunkGeneratorThread.cpp b/src/ChunkGeneratorThread.cpp index a42c211ad..f90134adf 100644 --- a/src/ChunkGeneratorThread.cpp +++ b/src/ChunkGeneratorThread.cpp @@ -18,7 +18,7 @@ const size_t QUEUE_SKIP_LIMIT = 500; cChunkGeneratorThread::cChunkGeneratorThread(void) : - Super("cChunkGeneratorThread"), + Super("Chunk Generator"), m_Generator(nullptr), m_PluginInterface(nullptr), m_ChunkSink(nullptr) diff --git a/src/ChunkSender.cpp b/src/ChunkSender.cpp index e40714472..2ab9a5a4d 100644 --- a/src/ChunkSender.cpp +++ b/src/ChunkSender.cpp @@ -59,7 +59,7 @@ public: // cChunkSender: cChunkSender::cChunkSender(cWorld & a_World) : - Super("ChunkSender"), + Super("Chunk Sender"), m_World(a_World), m_Serializer(m_World.GetDimension()) { diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 6c114897a..776ae5b26 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -21,7 +21,7 @@ const int CYCLE_MILLISECONDS = 100; cDeadlockDetect::cDeadlockDetect(void) : - Super("DeadlockDetect"), + Super("Deadlock Detector"), m_IntervalSec(1000) { } diff --git a/src/Globals.h b/src/Globals.h index 0a5607c2f..d5af4fa11 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -78,22 +78,24 @@ // OS-dependent stuff: #ifdef _WIN32 - + #define NOMINMAX // Windows SDK defines min and max macros, messing up with our std::min and std::max usage. #define WIN32_LEAN_AND_MEAN - #define _WIN32_WINNT _WIN32_WINNT_WS03 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher + #define _WIN32_WINNT 0x0501 // We want to target Windows XP with Service Pack 2 & Windows Server 2003 with Service Pack 1 and higher. - // Windows SDK defines min and max macros, messing up with our std::min and std::max usage - #define NOMINMAX + // Use CryptoAPI primitives when targeting a version that supports encrypting with AES-CFB8 smaller than a full block at a time. + #define PLATFORM_CRYPTOGRAPHY (_WIN32_WINNT >= 0x0602) #include #include #include // IPv6 stuff - // Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant + // Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant: #ifdef GetFreeSpace #undef GetFreeSpace #endif // GetFreeSpace #else + #define PLATFORM_CRYPTOGRAPHY 0 + #include #include #endif diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 015bfb68a..d5e37ff2f 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -100,7 +100,7 @@ public: // cLightingThread: cLightingThread::cLightingThread(cWorld & a_World): - Super("cLightingThread"), + Super("Lighting Executor"), m_World(a_World), m_MaxHeight(0), m_NumSeeds(0) diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp index 4190acb26..a79fee9c6 100644 --- a/src/OSSupport/IsThread.cpp +++ b/src/OSSupport/IsThread.cpp @@ -2,7 +2,6 @@ // IsThread.cpp // Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. -// This class will eventually suupersede the old cThread class #include "Globals.h" #include "IsThread.h" @@ -11,46 +10,12 @@ -#if defined(_MSC_VER) && !defined(NDEBUG) - // Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - - const DWORD MS_VC_EXCEPTION = 0x406D1388; - #pragma pack(push, 8) - struct THREADNAME_INFO - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1 = caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; - #pragma pack(pop) - - /** Sets the name of a thread with the specified ID - (When in MSVC, the debugger provides "thread naming" by catching special exceptions) - */ - static void SetThreadName(std::thread * a_Thread, const char * a_ThreadName) - { - THREADNAME_INFO info { 0x1000, a_ThreadName, GetThreadId(a_Thread->native_handle()), 0 }; - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - } -#endif // _MSC_VER && !NDEBUG - - - - - //////////////////////////////////////////////////////////////////////////////// // cIsThread: -cIsThread::cIsThread(const AString & a_ThreadName) : +cIsThread::cIsThread(AString && a_ThreadName) : m_ShouldTerminate(false), - m_ThreadName(a_ThreadName) + m_ThreadName(std::move(a_ThreadName)) { } @@ -69,6 +34,36 @@ cIsThread::~cIsThread() void cIsThread::DoExecute(void) { +#if defined(_MSC_VER) && !defined(NDEBUG) + /* Sets the name of this thread. + (When in MSVC, the debugger provides "thread naming" by catching special exceptions) + Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ + +#pragma pack(push, 8) + struct THREADNAME_INFO + { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1 = caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + }; +#pragma pack(pop) + + if (!m_ThreadName.empty()) + { + const DWORD NAME_EXCEPTION = 0x406D1388; + const THREADNAME_INFO Name = { 0x1000, m_ThreadName.c_str(), -1, 0 }; + + __try + { + RaiseException(NAME_EXCEPTION, 0, sizeof(Name) / sizeof(ULONG_PTR), reinterpret_cast(&Name)); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +#endif + m_evtStart.Wait(); Execute(); } @@ -84,13 +79,6 @@ bool cIsThread::Start(void) // Initialize the thread: m_Thread = std::thread(&cIsThread::DoExecute, this); - #if defined(_MSC_VER) && !defined(NDEBUG) - if (!m_ThreadName.empty()) - { - SetThreadName(&m_Thread, m_ThreadName.c_str()); - } - #endif - // Notify the thread that initialization is complete and it can run its code safely: m_evtStart.Set(); @@ -120,7 +108,7 @@ void cIsThread::Stop(void) bool cIsThread::Wait(void) { - LOGD("Waiting for thread %s to finish", m_ThreadName.c_str()); + LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str()); if (m_Thread.joinable()) { try @@ -130,11 +118,11 @@ bool cIsThread::Wait(void) } catch (const std::system_error & a_Exception) { - LOGERROR("%s error %i: could not join thread %s; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); + LOGERROR("%s error %i: could not join the %s thread; %s", __FUNCTION__, a_Exception.code().value(), m_ThreadName.c_str(), a_Exception.code().message().c_str()); return false; } } - LOGD("Thread %s finished", m_ThreadName.c_str()); + LOGD("The %s thread finished", m_ThreadName.c_str()); return true; } diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index d882dbf8a..6a515a6de 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -32,7 +32,7 @@ protected: std::atomic m_ShouldTerminate; public: - cIsThread(const AString & a_ThreadName); + cIsThread(AString && a_ThreadName); virtual ~cIsThread(); /** Starts the thread; returns without waiting for the actual start. */ diff --git a/src/OSSupport/NetworkLookup.cpp b/src/OSSupport/NetworkLookup.cpp index 5cd7ecfc4..8a0e54015 100644 --- a/src/OSSupport/NetworkLookup.cpp +++ b/src/OSSupport/NetworkLookup.cpp @@ -11,7 +11,7 @@ cNetworkLookup::cNetworkLookup() : - cIsThread("NetworkLookup") + cIsThread("Network Lookup Executor") { } diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index e23691edc..8b536d4e1 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -26,7 +26,7 @@ cAuthenticator::cAuthenticator(void) : - Super("cAuthenticator"), + Super("Authenticator"), m_Server(DEFAULT_AUTH_SERVER), m_Address(DEFAULT_AUTH_ADDRESS), m_ShouldAuthenticate(true) diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 8a3868ecc..244052a36 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -237,7 +237,7 @@ class cMojangAPI::cUpdateThread: public: cUpdateThread(cMojangAPI & a_MojangAPI): - Super("cMojangAPI::cUpdateThread"), + Super("MojangAPI Updater"), m_MojangAPI(a_MojangAPI) { } diff --git a/src/Root.cpp b/src/Root.cpp index a1023e8e9..62d50c28c 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -1046,7 +1046,6 @@ void cRoot::TransitionNextState(NextState a_NextState) s_StopEvent.Set(); #ifdef WIN32 - DWORD Length; INPUT_RECORD Record { diff --git a/src/Server.cpp b/src/Server.cpp index cd44e948f..a0b9f245d 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -71,7 +71,7 @@ public: // cServer::cTickThread: cServer::cTickThread::cTickThread(cServer & a_Server) : - Super("ServerTickThread"), + Super("Server Ticker"), m_Server(a_Server) { } diff --git a/src/World.cpp b/src/World.cpp index 3be923fff..84f8bb9c6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -96,7 +96,7 @@ cWorld::cLock::cLock(const cWorld & a_World) : // cWorld::cTickThread: cWorld::cTickThread::cTickThread(cWorld & a_World) : - Super(Printf("WorldTickThread: %s", a_World.GetName().c_str())), + Super(Printf("World Ticker (%s)", a_World.GetName().c_str())), m_World(a_World) { } diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 8f6259841..2f566a083 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -38,7 +38,7 @@ protected: // cWorldStorage: cWorldStorage::cWorldStorage(void) : - Super("cWorldStorage"), + Super("World Storage Executor"), m_World(nullptr), m_SaveSchema(nullptr) { diff --git a/src/mbedTLS++/AesCfb128Decryptor.cpp b/src/mbedTLS++/AesCfb128Decryptor.cpp index 6243a3ded..3efe95dbe 100644 --- a/src/mbedTLS++/AesCfb128Decryptor.cpp +++ b/src/mbedTLS++/AesCfb128Decryptor.cpp @@ -13,7 +13,7 @@ cAesCfb128Decryptor::cAesCfb128Decryptor(void) : m_IsValid(false) { -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) if (!CryptAcquireContext(&m_Aes, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { throw std::system_error(GetLastError(), std::system_category()); @@ -30,7 +30,7 @@ cAesCfb128Decryptor::cAesCfb128Decryptor(void) : cAesCfb128Decryptor::~cAesCfb128Decryptor() { // Clear the leftover in-memory data, so that they can't be accessed by a backdoor: -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) CryptReleaseContext(m_Aes, 0); #else mbedtls_aes_free(&m_Aes); @@ -45,7 +45,7 @@ void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16]) { ASSERT(!IsValid()); // Cannot Init twice -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) struct Key { PUBLICKEYSTRUC Header; @@ -77,7 +77,7 @@ void cAesCfb128Decryptor::ProcessData(std::byte * const a_EncryptedIn, const siz { ASSERT(IsValid()); // Must Init() first -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) ASSERT(a_Length <= std::numeric_limits::max()); DWORD Length = static_cast(a_Length); diff --git a/src/mbedTLS++/AesCfb128Decryptor.h b/src/mbedTLS++/AesCfb128Decryptor.h index a2c9d6a05..1fee2bbba 100644 --- a/src/mbedTLS++/AesCfb128Decryptor.h +++ b/src/mbedTLS++/AesCfb128Decryptor.h @@ -9,7 +9,7 @@ #pragma once -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) #include #else #include "mbedtls/aes.h" @@ -38,7 +38,7 @@ public: protected: -#ifdef _WIN32 +#if PLATFORM_CRYPTOGRAPHY && defined(_WIN32) HCRYPTPROV m_Aes; HCRYPTKEY m_Key; #else